/* Barlow / Barlow Condensed — pakket lokalt (OFL-lisens). Ingen eksterne kall;
   appen er selvforsynt offline. Kilde: Google Fonts, lastet ned 2026-07-18. */
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-condensed-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/barlow-condensed-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-condensed-500-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/barlow-condensed-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-condensed-600-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/barlow-condensed-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-condensed-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Barlow Condensed';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/barlow-condensed-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* styles.css — Dronestudiet Admin. Lys, ryddig. Aksent mørk politiblå. */

:root {
  --aksent: #5980a6;
  --aksent-lys: #416180;
  --aksent-mork: #1d2d3d;
  /* Høyden på topplinja — logorubrikken i sidefeltet OG toppfeltet. Ett tall,
     to steder: understreken skal gå ubrutt tvers over skjermen. */
  --topplinje: 4rem;
  --gronn: #2e7d32;
  --gul: #f9a825;
  --rod: #c62828;
  --graa: #98989b;
  --tekst: #1d1f20;
  --tekst-svak: #6b6e73;
  --bg: #e9e9ea;
  --flate: #f2f2f3;
  --kant: #d4d4d7;
  --kant-mork: #b7b7ba;
  --skygge: 0 1px 2px color-mix(in srgb, #2b2b2d 14%, transparent);
  --radius: 0;
  /* TYPESKALA. Fila hadde 31 ulike rem-verdier - flere av dem et haarstraa
     fra hverandre (0.68 mot 0.688, 0.80 mot 0.812 mot 0.82, fire trinn mellom
     0.84 og 0.88). Det er ikke en skala, det er drift: hver enkelt regel er
     rimelig, men til sammen gir de et rotete inntrykk uten at noen kan peke
     paa hvor.
     Naer-duplikatene er snappet. Skalaen under er de trinnene som faktisk
     brukes - hold deg til dem framfor aa finne opp et nytt tall. */
  --t-mikro: 0.68rem;     /* versaletiketter, fotnoter */
  --t-liten: 0.78rem;     /* merker, hjelpetekst */
  --t-brod: 0.85rem;      /* tabellceller, inline-felt */
  --t-normal: 0.9rem;     /* broedtekst, knapper */
  --t-stor: 1rem;
  --t-tittel: 1.1rem;     /* kortoverskrifter */
  --t-overskrift: 1.5rem;

  --font: "Barlow", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-overskrift: "Barlow Condensed", "Barlow", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  font-family: var(--font);
  /* SLAAR AV IOS SAFARIS AUTOMATISKE TEKSTFORSTOERRING.
     Uten denne kjoerer Safari paa iPhone sin egen «text autosizing»: den
     blaaser opp skrift blokk for blokk etter hvor mye tekst blokken har.
     Resultatet i pensumlista var at hver rad fikk SIN egen stoerrelse selv
     om CSS-regelen er den samme for alle - korte titler ble stoerst, lange
     minst. Det er ikke synlig i en skrivebordsnettleser, og lot seg derfor
     ikke gjenskape ved maaling her; det ble meldt fra en iPhone.
     `100%` og ikke `none`: `none` slaar ogsaa av brukerens egen zoom. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  font-size: 15px;
  color: var(--tekst);
  background: var(--bg);
  line-height: 1.45;
}

h1, h2, h3, h4 { margin: 0 0 0.5em; font-family: var(--font-overskrift); font-weight: 600; color: var(--aksent-mork); line-height: 1.14; letter-spacing: -0.01em; }
a { color: var(--aksent-lys); }
a.lenke { color: var(--aksent-lys); text-decoration: none; }
a.lenke:hover { text-decoration: underline; }

.oppstart-laster { padding: 3rem; text-align: center; color: var(--tekst-svak); }

/* --------------------------------------------------------------------- */
/* Auth-sider                                                            */
/* --------------------------------------------------------------------- */
.auth-side {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  background-image:
    linear-gradient(color-mix(in srgb, var(--aksent) 9%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--aksent) 9%, transparent) 1px, transparent 1px);
  background-size: 26px 26px;
  padding: 1rem;
}
.auth-boks {
  background: var(--flate);
  padding: 2rem 2.25rem;
  border: 1px solid var(--kant);
  border-top: 3px solid var(--aksent);
  border-radius: var(--radius);
  box-shadow: 0 8px 30px rgba(20, 40, 70, 0.14);
  width: 100%;
  max-width: 400px;
}
.auth-boks h1 { text-align: left; color: var(--aksent); margin-bottom: 0.2rem; }
.auth-undertittel { text-align: left; color: var(--tekst-svak); margin-top: 0; margin-bottom: 1.5rem; }
.advarsel-boks {
  background: #fff5e6;
  border: 1px solid var(--gul);
  border-radius: var(--radius);
  padding: 0.75rem 1rem;
  font-size: 0.9rem;
  margin-bottom: 1.25rem;
  color: #7a5200;
}
.feiltekst { color: var(--rod); }

/* --------------------------------------------------------------------- */
/* Hovedlayout                                                           */
/* --------------------------------------------------------------------- */
.layout { display: flex; min-height: 100vh; }
.sidefelt {
  width: 220px;
  flex-shrink: 0;
  background: var(--aksent-mork);
  color: #eaf0f7;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}
/* Hamburgeren gjelder bare telefon — se media-spørringen for små skjermer. */
.meny-knapp { display: none; }

/* Logorubrikken og toppfeltet er ÉN vannrett linje på tvers av sidefeltet og
   hovedflaten. De deler høyde gjennom variabelen under, slik at understreken
   går ubrutt tvers over skjermen — to tall som skulle vært like, men som var
   satt hver for seg, er nettopp det som driver fra hverandre. */
.sidefelt-logo {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.85rem 1.25rem;
  min-height: var(--topplinje);
  box-sizing: border-box;
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.logo-merke {
  background: var(--flate);
  color: var(--aksent);
  font-weight: 700;
  border-radius: 6px;
  padding: 0.25rem 0.5rem;
  font-size: 0.9rem;
}
.logo-tekst { font-weight: 600; font-size: 1.05rem; }
.nav-liste { list-style: none; margin: 0.5rem 0; padding: 0; }
.nav-liste li { margin: 0; }
.nav-lenke {
  display: block;
  padding: 0.32rem 1.25rem;
  color: #cdd9e8;
  text-decoration: none;
  font-size: 0.9rem;
  line-height: 1.35;
  border-left: 3px solid transparent;
}
.nav-lenke:hover { background: rgba(255, 255, 255, 0.07); color: #fff; }
.nav-lenke.aktiv { background: rgba(255, 255, 255, 0.12); color: #fff; border-left-color: #fff; font-weight: 600; }

.hoved { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.toppfelt {
  background: var(--flate);
  border-bottom: 1px solid var(--kant);
  padding: 0.6rem 1.5rem;
  min-height: var(--topplinje);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 20;
}
.toppfelt-venstre { display: flex; align-items: center; gap: 0.5rem; }
.pulje-etikett { color: var(--tekst-svak); font-size: 0.9rem; }
/* Studievelgeren. Står FORAN puljevelgeren fordi den avgrenser den: studiet er
   rammen, kullet er valget innenfor. Hele bolken skjules når installasjonen
   bare har ett studie — se fyllStudieVelger i app.js. */
/* Kategori man ser, men ikke eier. Dempet så det er tydelig at innholdet er
   opplysning og ikke et skjema — se kategoriKort i tilganger.js. */
.tilgang-kategori-laast { opacity: 0.78; }
.studie-bolk { display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.studie-bolk.skjult { display: none; }
#studie-velger { min-width: 180px; }
.pulje-velger, .filter-velger, .rapport-velger, .status-select, .liten-input, .celle-input {
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--kant-mork);
  border-radius: var(--radius);
  background: var(--flate);
  color: var(--tekst);
}
.pulje-velger { min-width: 220px; }
.innhold { padding: 1.5rem; flex: 1; }

/* --------------------------------------------------------------------- */
/* Knapper                                                               */
/* --------------------------------------------------------------------- */
.knapp {
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.5rem 0.95rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}
.knapp-primar { background: var(--aksent); color: #fff; }
.knapp-primar:hover { background: var(--aksent-lys); }
.knapp-sekundar { background: var(--flate); color: var(--aksent); border-color: var(--kant-mork); }
.knapp-sekundar:hover { background: #e7e7ea; }
.knapp-fare { background: var(--rod); color: #fff; }
.knapp-fare:hover { background: #a71e1e; }
.knapp-liten { padding: 0.3rem 0.6rem; font-size: 0.82rem; }
.knapp:disabled { opacity: 0.5; cursor: not-allowed; }

.ikon-knapp {
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.2rem 0.4rem;
  border-radius: var(--radius);
  color: var(--tekst-svak);
  line-height: 1;
}

/* Puljer — kompakt samlingssammendrag (antall + utvid-pil) i stedet for at
   hver samlingsdato listes rett i tabellraden. */
.kol-samlinger { max-width: 15rem; }
.sammendrag-toggle {
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  font-family: inherit;
  font-size: 0.88rem;
  color: var(--aksent-lys);
  white-space: nowrap;
}
.sammendrag-toggle:hover { text-decoration: underline; }
.sammendrag-pil { display: inline-block; width: 0.9em; }
.pulje-samlinger-liste {
  margin-top: 0.35rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  font-size: 0.85rem;
  color: var(--tekst);
}

/* Personvelger «Ny søker» — personer allerede lagt til puljen sorteres
   nederst og gråes ut (mest konsistent browserstøtte: color + background,
   ikke opacity, siden mange nettlesere ikke lar option arve opacity). */
option.valg-inaktiv { color: var(--tekst-svak); background: #ececed; font-style: italic; }
.ikon-knapp:hover { background: #e7e7ea; color: var(--aksent); }
.ikon-knapp.ikon-fare:hover { background: #fdecec; color: var(--rod); }
.ikon-knapp:disabled { opacity: 0.35; cursor: not-allowed; }

/* --------------------------------------------------------------------- */
/* Sidehode og kort                                                      */
/* --------------------------------------------------------------------- */
.side-hode {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
  flex-wrap: wrap;
}
.side-tittel { margin: 0; font-size: 1.5rem; }
.side-handlinger { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.side-meta { color: var(--tekst-svak); font-size: 0.9rem; }

.kort {
  background: var(--flate);
  border: 1px solid var(--kant);
  border-top: 3px solid var(--aksent);
  border-radius: var(--radius);
  box-shadow: var(--skygge);
  padding: 1.1rem 1.25rem;
  margin-bottom: 1.25rem;
}
.kort-tittel { font-size: 1.05rem; margin-bottom: 0.75rem; }

.tilbake-lenke {
  display: inline-block;
  margin-bottom: 0.75rem;
  color: var(--tekst-svak);
  text-decoration: none;
  font-size: 0.9rem;
}
.tilbake-lenke:hover { color: var(--aksent); }

.verktoy-linje { display: flex; gap: 0.5rem; align-items: center; margin-bottom: 0.9rem; flex-wrap: wrap; }
.verktoy-linje .filtre { margin-left: auto; display: flex; gap: 0.75rem; }
.filter-felt { display: flex; flex-direction: column; font-size: 0.78rem; color: var(--tekst-svak); gap: 0.15rem; }

/* --------------------------------------------------------------------- */
/* Tabeller                                                              */
/* --------------------------------------------------------------------- */
.tabell-wrap { overflow-x: auto; }

/* Søkefeltet over lange lister. Terskelen ligger i sorterbarTabell — her er
   bare utseendet. Telleren står til høyre og sier «12 av 125» mens man skriver,
   slik at man ser om søket traff noe før man leter i tabellen. */
/* Tittel- og punktkolonnene er de eneste som TÅLER brytning — resten av
   cellene er inline-block-merker som ikke kan brekkes. Uten denne regelen
   stakk lange ord («luftfartstilsynets», «formidlingstjeneste») ut av cella
   i stedet for å brekke, og en smalere kolonne gjorde det bare verre. */
/* HI-kolonnen paa leksjonsoversikten. Et navn som «Kristoffersen, Bjorn-Olav»
   kan ikke krympe under sin egen bredde, og dyttet tabellen 5 px ut i en
   sidelengs rulling. Med `table-layout: fixed` holder avkortingen paa cella;
   hele navnet ligger i `title`. */
.tabell td.kol-hi {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.tabell td.kol-brytbar, .matrise-punkt-tekst {
  overflow-wrap: break-word;
  word-break: break-word;
}

.tabell-boks { display: flex; flex-direction: column; }
.tabell-verktoy {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.5rem;
}
.tabell-sok { flex: 0 1 20rem; min-width: 0; }
.tabell-teller {
  font-size: 0.82rem;
  color: var(--tekst-svak);
  white-space: nowrap;
}
.tabell { width: 100%; border-collapse: collapse; background: var(--flate); font-size: 0.9rem; }
.tabell th, .tabell td {
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--kant);
  vertical-align: top;
}
.tabell thead th {
  background: #e7e7ea;
  color: var(--aksent-mork);
  font-weight: 600;
  font-size: 0.82rem;
  white-space: nowrap;
  position: sticky;
  top: 0;
}
.tabell th.sorterbar { cursor: pointer; user-select: none; }
.tabell th.sorterbar:hover { background: #dcdce0; }
.tabell tbody tr:hover { background: #f0f0f1; }
.tabell tr.klikkbar { cursor: pointer; }
.tabell-tett th, .tabell-tett td { padding: 0.4rem 0.55rem; }
.tabell-tom { text-align: center; color: var(--tekst-svak); font-style: italic; padding: 1.25rem; }
.kol-handling { width: 1%; white-space: nowrap; text-align: right; }
.kol-smal { width: 3rem; }
.rad-handlinger { display: inline-flex; gap: 0.25rem; align-items: center; }
.sum-rad td { font-weight: 600; background: #ececee; }
.total-rad td { border-top: 2px solid var(--kant-mork); }
tfoot .sum-rad td { border-bottom: none; }

/* --------------------------------------------------------------------- */
/* Statusmerker (badges)                                                 */
/* --------------------------------------------------------------------- */
.merke {
  display: inline-block;
  padding: 0.12rem 0.5rem;
  border-radius: 10px;
  font-size: 0.78rem;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
  line-height: 1.5;
}
.merke-gronn { background: var(--gronn); }
.merke-gul { background: var(--gul); color: #3a2c00; }
.merke-rod { background: var(--rod); }
.merke-graa { background: var(--graa); }

/* --------------------------------------------------------------------- */
/* Skjema                                                                */
/* --------------------------------------------------------------------- */
.skjema { display: grid; grid-template-columns: 1fr 1fr; gap: 0.85rem 1rem; }
.skjema-rad { display: flex; flex-direction: column; gap: 0.25rem; }
.skjema-rad-bred { grid-column: 1 / -1; }
.skjema-ledetekst { font-size: 0.82rem; color: var(--tekst-svak); font-weight: 500; }
.paakrevd { color: var(--rod); }
.skjema-input {
  font-family: inherit;
  font-size: 0.9rem;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--kant-mork);
  border-radius: var(--radius);
  background: var(--flate);
  color: var(--tekst);
  width: 100%;
}
.skjema-input:focus, .pulje-velger:focus, .status-select:focus {
  outline: none;
  border-color: var(--aksent-lys);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--aksent) 22%, transparent);
}
textarea.skjema-input { resize: vertical; min-height: 48px; }
textarea.auto-hoyde { overflow: hidden; }
.skjema-avkryssing-rad { display: flex; align-items: center; gap: 0.5rem; font-size: 0.9rem; cursor: pointer; }
.skjema-avkryssing { width: auto; }
.skjema-hjelp { font-size: 0.78rem; color: var(--tekst-svak); }
/* Kvittering ved autolagring. Uten den er lagringen usynlig, og da er det
   rimelig å lure på om noe ble lagret i det hele tatt. */
.lagret-merke {
  margin-left: 0.5rem; font-size: 0.72rem; font-weight: 600;
  color: var(--gronn); white-space: nowrap;
}
/* Overskrift som deler et langt skjema i bolker. Spenner begge kolonnene og
   har luft over seg — det er skillet som gjør at fjorten felter kan skummes. */
.skjema-gruppe {
  grid-column: 1 / -1;
  margin: 0.9rem 0 -0.2rem;
  padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--kant);
}
.skjema-gruppe:first-child { margin-top: 0; }
.skjema-gruppe-tittel {
  margin: 0;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--aksent-mork);
}
.skjema-gruppe-hjelp { margin: 0.15rem 0 0; font-size: 0.78rem; color: var(--tekst-svak); }
.skjema-feil { font-size: 0.78rem; color: var(--rod); min-height: 0.5rem; }
.skjema-knapper { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.5rem; }
/* Øktvinduet: veien videre til venstre, lagre/avbryt til høyre — samme rad.
   Den venstre knappen skjules når det ikke finnes en leksjon å åpne; høyre
   side blir da stående til høyre (margin-left: auto). */
.okt-knapper { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
  margin-top: 1rem; padding-top: 0.85rem; border-top: 1px solid var(--kant); }
.okt-knapper-hoyre { display: flex; gap: 0.5rem; margin-left: auto; }
.liten-input { width: 100%; min-width: 6rem; }
.celle-input { width: 100%; resize: vertical; font-size: 0.85rem; }
.status-select.liten { padding: 0.2rem 0.35rem; font-size: 0.82rem; }

/* --------------------------------------------------------------------- */
/* Modal                                                                 */
/* --------------------------------------------------------------------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(20, 35, 55, 0.5);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 3rem 1rem;
  z-index: 100;
  overflow-y: auto;
}
.modal {
  background: var(--flate);
  border-radius: 8px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
  width: 100%;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 6rem);
}
.modal-hode {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--kant);
}
.modal-tittel { margin: 0; font-size: 1.1rem; }
.modal-lukk {
  background: transparent; border: none; font-size: 1.5rem; line-height: 1;
  cursor: pointer; color: var(--tekst-svak); padding: 0 0.25rem;
}
.modal-lukk:hover { color: var(--rod); }
.modal-kropp { padding: 1.25rem; overflow-y: auto; }
.modal-footer {
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--kant);
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}
.bekreft-tekst { margin: 0; }

/* --------------------------------------------------------------------- */
/* Instruktøroversikt: puljedeltakelse med stegvis utfolding             */
/* --------------------------------------------------------------------- */
.kol-instr-puljer { min-width: 16rem; }
.instr-pulje-celle { display: flex; gap: 0.4rem; align-items: flex-start; }
.instr-pil { flex: none; margin-top: 0.1rem; }
.instr-pil:disabled { opacity: 0.3; cursor: default; }
.instr-eksp > td { background: var(--flate-alt, rgba(29, 45, 61, 0.03)); padding: 0.6rem 1rem; }
.instr-eksp-innhold { display: flex; flex-direction: column; gap: 0.9rem; }
.instr-eksp-pulje {
  border-left: 3px solid var(--aksent);
  padding-left: 0.75rem;
}
.instr-eksp-hode { margin-bottom: 0.35rem; }
.instr-eksp-gruppe { margin-top: 0.4rem; }
.instr-eksp-etikett {
  font-size: 0.76rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tekst-svak);
  margin-bottom: 0.15rem;
}

/* --------------------------------------------------------------------- */
/* Leksjonssiden: lesevisning                                            */
/*                                                                       */
/* Faktalinja svarer på når/hvor/hvor lenge/hvem i ett blikk. Bolkene    */
/* under er ren tekst, ikke skjemabokser — felter uten innhold utelates. */
/* --------------------------------------------------------------------- */
.leksjon-fakta {
  display: flex;
  flex-wrap: wrap;
  gap: 0 2rem;
  padding: 0.7rem 0.9rem;
  margin-bottom: 1.25rem;
  background: var(--flate);
  border: 1px solid var(--kant);
  border-left: 3px solid var(--aksent);
}
.leksjon-fakta-post { padding: 0.15rem 0; }
.leksjon-fakta-etikett {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tekst-svak);
}
.leksjon-fakta-verdi { font-size: 0.95rem; font-weight: 500; }

/* --------------------------------------------------------------------- */
/* Leksjonssida                                                          */
/*                                                                       */
/* Fanene (Leksjonsplan / Laeringsmaal / Tidsplan / Koblinger) er borte.  */
/* De fantes fordi sida var 6,1 skjermer hoey — men de loeste hoeyden ved */
/* aa gjemme tre firedeler av leksjonen. Det som baerer hoeyden naa er at */
/* TOMME FELT TAR ÉN LINJE (.lfelt-tom), ikke en boks paa 52px.          */
/*                                                                       */
/* Foerste utgave hadde ogsaa en sidespalte paa 21rem for maal og         */
/* koblinger. Den ble proevd og meldt som rotete: fire seksjoner med hver */
/* sine soekefelt og chips fikk under en tredjedel av bredden. Alt staar  */
/* naa i én kolonne.                                                     */
/* --------------------------------------------------------------------- */
.leksjon-hoved { display: flex; flex-direction: column; min-width: 0; }
.leksjon-hoved .kort { margin-bottom: 1rem; }

/* Koblingene er fire smaa ting og staar side om side. Stablet ville kortet
   blitt fire ganger saa hoeyt som innholdet trenger. */
.koblinger-rutenett {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem;
  align-items: start;
}
.koblinger-rutenett > div > h4:first-child,
.koblinger-rutenett h4 { margin: 0 0 0.4rem; font-size: 0.95rem; }
/* Forutsetningsseksjonen kommer med sin egen kortramme; inne i rutenettet
   ville den vaert en ramme inni en ramme. */
.koblinger-rutenett > .kort {
  background: none; border: none; box-shadow: none; padding: 0; margin: 0;
}

/* Inline koblingssoek. Erstatter en dialog med avhuking og «Lagre»: skriv,
   piltast, Enter. Trefflista ligger ABSOLUTT over innholdet under, ellers
   ville seksjonen hoppet i hoeyde for hvert tastetrykk. */
.kobling-sok-rad { margin-top: 0.6rem; }
.kobling-sokeboks { position: relative; }
.kobling-sok {
  font-family: inherit; font-size: 0.85rem; width: 100%;
  padding: 0.35rem 0.5rem; border: 1px solid var(--kant-mork);
  border-radius: var(--radius); background: var(--flate); color: var(--tekst);
}
.kobling-sok:focus { border-color: var(--aksent); background: #fff; outline: none; }
.kobling-treff {
  display: none; position: absolute; left: 0; right: 0; top: 100%; z-index: 20;
  background: var(--flate); border: 1px solid var(--kant-mork); border-top: none;
  box-shadow: var(--skygge); max-height: 15rem; overflow-y: auto;
}
.kobling-treff-apen { display: block; }
.kobling-treff-rad {
  padding: 0.35rem 0.5rem; font-size: 0.82rem; cursor: pointer;
  border-bottom: 1px solid var(--kant);
}
.kobling-treff-rad:last-child { border-bottom: none; }
.kobling-treff-rad:hover, .kobling-treff-rad.aktiv { background: #eaeef2; }
.kobling-treff-merknad { display: block; font-size: 0.72rem; color: var(--tekst-svak); }
.kobling-treff-tom { padding: 0.35rem 0.5rem; font-size: 0.82rem; color: var(--tekst-svak); }
.kobling-sok-hjelp { font-size: 0.72rem; color: var(--tekst-svak); margin-top: 0.25rem; }

/* Laeringsmaal. Én rad per maal: kategorimerke, den valgfrie gruppa, selve
   maalet, og handlingene. Erstattet en tabell med fem kolonner — «#» sa bare
   det samme som rekkefoelgen, og en tabellramme rundt fire rader er stoey. */
.mal-kompakt { display: flex; flex-direction: column; gap: 0.4rem; }
.mal-rad {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0.4rem; align-items: start;
}
.mal-kat {
  font-family: inherit; font-size: 0.7rem; font-weight: 700; line-height: 1;
  padding: 0.2rem 0.1rem 0.2rem 0.25rem; margin-top: 0.15rem;
  border: 1px solid var(--kant-mork); border-radius: var(--radius);
  background: var(--aksent-mork); color: #fff; cursor: pointer;
  /* Nedtrekkspila tar mer plass enn bokstaven i et felt paa denne stoerrelsen. */
  appearance: none; -webkit-appearance: none; text-align: center; width: 1.6rem;
}
.mal-kat[data-kat="ferdighet"] { background: var(--aksent); }
.mal-kat[data-kat="generell"] { background: var(--graa); }
.mal-kat:focus-visible { outline: 2px solid var(--aksent); outline-offset: 1px; }
.mal-tekst {
  font-family: inherit; width: 100%; resize: none;
  border: 1px solid transparent; border-radius: var(--radius);
  background: transparent; color: var(--tekst); padding: 0.1rem 0.25rem;
  overflow: hidden;
}
.mal-tekst { font-size: 0.85rem; }
.mal-tekst:hover { border-color: var(--kant); background: var(--flate); }
.mal-tekst:focus {
  border-color: var(--aksent); background: var(--flate); outline: none; color: var(--tekst);
}
.mal-handlinger { display: flex; gap: 0; }
.mal-handlinger .ikon-knapp { font-size: 0.75rem; padding: 0.1rem 0.15rem; }
.mal-verktoy { margin: 0.6rem 0 0.3rem; }

.gruppe-hode {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin-bottom: 0.7rem;
}
.gruppe-hode .seksjon-tittel { margin: 0; }
.gruppe-telling { font-size: 0.72rem; font-weight: 600; color: var(--tekst-svak); white-space: nowrap; }
.gruppe-telling-full { color: var(--gronn); }
.gruppe-telling-tom { color: var(--tekst-svak); }
/* Gul topplinje paa gruppen som mangler noe. Kortet har allerede en blaa
   topplinje, saa dette er en fargeendring og ikke et nytt element. */
.kort.leksjon-gruppe.kort-mangler { border-top-color: var(--gul); }
.gruppe-felter { display: flex; flex-direction: column; gap: 0.85rem; }

/* Ett felt. Utfylt: ledetekst + tekst. Tomt: én linje med «+ Skriv». */
.lfelt { min-width: 0; }
.lfelt-etikett {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--tekst-svak);
}
.lfelt-verdi { font-size: 0.95rem; white-space: pre-line; }
.lfelt-klikkbar { cursor: text; border: 1px solid transparent; margin: -1px -0.4rem; padding: 1px 0.4rem; }
.lfelt-klikkbar:hover { border-color: var(--kant-mork); background: var(--flate); }
.lfelt-klikkbar:focus-visible { outline: 2px solid var(--aksent); outline-offset: 1px; }
.lfelt-tom { border-top: 1px dashed var(--kant); padding-top: 0.5rem; }
.lfelt-tomknapp {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: inherit; text-align: left;
}
.lfelt-tomknapp .lfelt-etikett { text-transform: none; font-size: 0.85rem; letter-spacing: 0; }
.lfelt-skriv { font-size: 0.82rem; color: var(--aksent); font-weight: 500; }
.lfelt-tomknapp:hover .lfelt-skriv { text-decoration: underline; }
.lfelt-tomknapp:focus-visible { outline: 2px solid var(--aksent); outline-offset: 2px; }
/* byggSkjema lager et todelt rutenett. Ett felt trenger én kolonne. */
.lfelt-skjema { display: block; }
.lfelt-skjema .skjema-rad-bred { grid-column: auto; }

/* Et «felt» som egentlig er en liste med egne skrivinger — hjelpeinstruktørene
   under hovedinstruktøren. Skillestreken over gjør at den leses som neste post
   i kortet og ikke som en fortsettelse av nedtrekket rett før. */
.lfelt-liste { border-top: 1px dashed var(--kant); padding-top: 0.5rem; }
.hjelpeinstr .merke-samling { margin: 0.3rem 0 0; }
.hjelpeinstr-tom { font-size: 0.9rem; }
.hjelpeinstr .hjelpetekst { margin-top: 0.4rem; }
/* Rolle + søk på samme linje: rollen velges først, så personen. */
.hjelpeinstr-legg { display: flex; gap: 0.5rem; align-items: flex-start; flex-wrap: wrap; margin-top: 0.4rem; }
.hjelpeinstr-legg .hjelpeinstr-rolle { width: auto; flex: 0 0 auto; }
.hjelpeinstr-legg > :last-child { flex: 1 1 14rem; }

/* Fremdriftslinja. Svarer paa «hva mangler» uten at man maa skrolle etter
   hull. Nevneren er feltene KATEGORIEN ser — se tegnFremdrift. */
.fremdrift {
  display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
  background: var(--flate); border: 1px solid var(--kant);
  border-left: 3px solid var(--gul);
  padding: 0.55rem 0.85rem; margin-bottom: 1rem;
}
.fremdrift-full { border-left-color: var(--gronn); }
.fremdrift-maal { display: flex; align-items: center; gap: 0.6rem; }
.fremdrift-spor { width: 7rem; height: 7px; background: var(--kant-mork); }
.fremdrift-fyll { height: 100%; background: var(--aksent); }
.fremdrift-tall { font-size: 0.82rem; font-weight: 600; white-space: nowrap; }
.fremdrift-mangler { display: flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; font-size: 0.8rem; }
.fremdrift-mangler .knapp { padding: 0.15rem 0.5rem; font-size: 0.78rem; }
.fremdrift-ferdig { font-size: 0.82rem; color: var(--gronn); font-weight: 600; }

.leksjon-bolk { margin-bottom: 1.5rem; }
/* Ledetekst til venstre, innhold til høyre. Stablet tok hvert felt to linjer
   ekstra, og med fjorten felter ble sida flere skjermer lengre enn den trengte.
   Kolonnebredden er fast slik at alle verdiene starter på samme sted — det er
   det som gjør at øyet kan skanne nedover uten å lete. */
.leksjon-def {
  display: grid;
  grid-template-columns: minmax(9rem, 15rem) minmax(0, 1fr);
  gap: 0.55rem 1.5rem;
  margin: 0;
  align-items: start;
}
/* Ledetekstene står i svart, ikke dempet grått: de er navigasjonen gjennom
   leksjonen — det studenten leter etter når hen skanner ned siden. Dempet grå
   på 0.78rem versaler er den svakeste kombinasjonen i appen. */
.leksjon-def dt {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tekst);
  font-weight: 700;
  /* I rutenettet gir en toppmargin skjev linjeføring mot verdien ved siden av.
     Den lille forskyvningen retter opp for at verdien har større skriftgrad. */
  margin: 0;
  padding-top: 0.12rem;
  line-height: 1.4;
}
.leksjon-def dd { margin: 0; min-width: 0; }

/* Under ~800 px er to kolonner for trangt: ledeteksten blir smalere enn ordet.
   Da stables de igjen, som før. */
@media (max-width: 800px) {
  .leksjon-def { grid-template-columns: 1fr; gap: 0.15rem; }
  .leksjon-def dt { margin-top: 0.8rem; }
  .leksjon-def dt:first-child { margin-top: 0; }
}

/* I vinduet er plassen trangere enn på sida — der skal teksten ha bredden,
   ikke ledetekstkolonnen. */
.modal .leksjon-def { grid-template-columns: minmax(7rem, 11rem) minmax(0, 1fr); }

/* Kategoriblokkene i målvisningen spenner begge kolonnene: de har sin egen
   dt/dd inni seg, og skal ikke presses inn i ledetekstkolonnen. */
.mal-kategori { display: contents; }
/* Fritekst fra basen: linjeskift skal telle, men ikke rives fra hverandre. */
.leksjon-tekst { white-space: pre-wrap; font-size: 0.9rem; max-width: 62ch; }
.leksjon-pensum { margin-top: 0.5rem; }

/* --------------------------------------------------------------------- */
/* Pensumlista på leksjonssiden                                          */
/*                                                                       */
/* Liste framfor merker: hver post har sine egne åpne-lenker, og de får   */
/* ikke plass i en merkeboble uten å bli uleselige.                      */
/* --------------------------------------------------------------------- */
.pensum-liste { display: flex; flex-direction: column; gap: 0.3rem; }
.pensum-post {
  display: flex;
  align-items: baseline;
  /* Lenkene faller ned på egen linje FØR tittelen presses sammen. Uten dette
     tok et langt filnavn 606 px av 668, tittelen satt igjen med 30 px og brøt
     ett tegn per linje — én post ble 348 px høy mot 35 for naboene. */
  flex-wrap: wrap;
  gap: 0.35rem 0.75rem;
  padding: 0.45rem 0.6rem;
  background: var(--flate);
  border: 1px solid var(--kant);
}
/* Basis, ikke auto: tittelen ber om reell plass, og er det ikke rom til både
   den og lenkene, brytes raden i to i stedet for at én av dem knuses. */
.pensum-post-tittel { flex: 1 1 20rem; min-width: 0; font-size: 0.9rem; }
.pensum-post-apne {
  flex: 0 1 auto;
  min-width: 0;
  margin-left: auto;      /* høyrestilt når begge får plass på samme linje */
  display: flex;
  gap: 0.5rem;
  font-size: 0.85rem;
  max-width: 100%;
}
.pensum-apne {
  color: var(--aksent-lys);
  text-decoration: none;
  /* Filnavn kan være vilkårlig lange. De klippes med ellipse — hele navnet
     ligger i title-attributtet, og filen åpnes uansett med ett klikk. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 24rem;
  cursor: pointer;
}
.pensum-apne:hover { text-decoration: underline; }

/* Filnavnet i «Lenke/fil»-kolonnen: klippes framfor å tvinge kolonnen bred.
   Hele navnet ligger i title-attributtet, og filen åpnes med ett klikk. */
.merke-samling-post > .lenke {
  display: inline-block;
  max-width: 6rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* --------------------------------------------------------------------- */
/* Timeføring i instruktørtabellen                                       */
/*                                                                       */
/* Cella leses ovenfra og ned: dager er hovedtallet (det er dager som gir */
/* tillegg), timer sekundært, tilleggene som en setning under. Fire like  */
/* store merker side om side ga ingen leserekkefølge.                    */
/* --------------------------------------------------------------------- */
.tf-celle { display: flex; align-items: center; gap: 0.75rem; }
.tf-tall { flex: 1 1 auto; min-width: 0; line-height: 1.3; }
/* Hovedlinja ARVER tabellens 0.9rem. Den sto på 1.05rem og ropte høyere enn
   navnekolonnen ved siden av — vekten skal bære betoningen, ikke størrelsen.
   Undertallet ligger på 0.8rem, samme trinn som øvrig sekundærtekst. */
.tf-hovedtall strong { font-weight: 600; }
.tf-undertall { font-size: 0.82rem; }
.tf-knapp { flex: 0 0 auto; padding: 0.15rem 0.6rem; font-size: 0.82rem; line-height: 1.4; }
.tf-laast { display: inline-flex; align-items: center; gap: 0.35rem; font-size: 0.82rem; }

/* Nøkkeltall: de to størrelsene som skal ut av en timeføring. */
.tf-ruter { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.5rem; margin-bottom: 0.7rem; }
.tf-rute { background: var(--flate); border: 1px solid var(--kant); padding: 0.5rem 0.7rem; }
.tf-rute-etikett { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--tekst-svak); }
.tf-rute-verdi { font-size: 1.5rem; font-weight: 600; font-family: var(--font-overskrift); color: var(--aksent-mork); line-height: 1.2; }
.tf-rute-enhet { font-size: 0.82rem; font-weight: 400; color: var(--tekst-svak); font-family: var(--font); }
/* «Bare mine timer» står i verktøylinja ved siden av grupperingsknappene, og
   skal stå på samme grunnlinje som dem — derav padding framfor margin. */
.tf-mine-bryter { display: inline-flex; align-items: center; gap: 0.4rem; padding-bottom: 0.4rem; white-space: nowrap; cursor: pointer; }
.tf-mine-bryter input { cursor: pointer; }

/* Linja i to nivåer: NÅR over, HVA under. */
.tf-liste { display: flex; flex-direction: column; gap: 0.4rem; }
.tf-linje { background: var(--flate); border: 1px solid var(--kant); padding: 0.5rem 0.7rem; }
.tf-linje-ny { background: transparent; border-style: dashed; border-color: var(--kant-mork); }
/* Avvik som kantstripe, ikke et lite merke: det skal fanges i skanningen. */
.tf-linje-avvik { border-left: 3px solid var(--gul); }
.tf-linje-nar { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.tf-linje-hva { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.45rem; flex-wrap: wrap; }
.tf-strekk { flex: 1 1 auto; }
.tf-timer { font-weight: 600; min-width: 3.5rem; }
.tf-dato { width: 9.5rem; }
.tf-tid { width: 6.5rem; }
.tf-samling { flex: 1 1 14rem; min-width: 12rem; }
.tf-kommentar { flex: 1 1 10rem; min-width: 8rem; }
.tf-avvik { margin-top: 0.4rem; font-size: 0.78rem; color: #7a5200; }

/* Raden som nettopp flyttet seg lyser kort opp. Flyttingen alene forteller at
   NOE skjedde; uthevingen forteller HVILKEN rad det gjaldt. */
@keyframes tf-flyttet {
  from { background: color-mix(in srgb, var(--aksent) 22%, var(--flate)); }
  to { background: var(--flate); }
}
.tf-linje-flyttet { animation: tf-flyttet 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .tf-linje-flyttet { animation-duration: 0.01ms; }
}
.tf-tom { padding: 0.7rem; }

/* Tillegg: tre gjensidig utelukkende valg. En dag kan bare ha ett — og det
   vises i kontrollen framfor å ligge skjult i et nedtrekk. */
.tf-segment { display: inline-flex; border: 1px solid var(--kant-mork); flex: 0 0 auto; }
.tf-segment-knapp {
  font-family: inherit;
  font-size: 0.82rem;
  padding: 0.28rem 0.7rem;
  border: 0;
  border-left: 1px solid var(--kant);
  background: var(--flate);
  color: var(--tekst-svak);
  cursor: pointer;
}
.tf-segment-knapp:first-child { border-left: 0; }
.tf-segment-knapp:hover:not(.aktiv):not(:disabled) { background: var(--bg); color: var(--tekst); }
.tf-segment-knapp.aktiv { background: var(--aksent); color: #fff; font-weight: 500; }
.tf-segment-knapp:disabled { cursor: default; opacity: 0.6; }

.tf-legg-til {
  margin-top: 0.5rem;
  font-family: inherit;
  font-size: 0.85rem;
  padding: 0.45rem 0.8rem;
  width: 100%;
  text-align: left;
  border: 1px dashed var(--kant-mork);
  background: transparent;
  color: var(--tekst-svak);
  cursor: pointer;
}
.tf-legg-til:hover { background: var(--flate); color: var(--tekst); border-color: var(--aksent); }

/* --------------------------------------------------------------------- */
/* Flervalgsmodal (koblinger)                                            */
/* --------------------------------------------------------------------- */
.flervalg { display: flex; flex-direction: column; gap: 0.6rem; }
.flervalg-sok { width: 100%; }
.flervalg-bryter { align-self: flex-start; }
.flervalg-grupper { display: flex; flex-direction: column; gap: 0.9rem; }
.flervalg-gruppe-hode {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
  min-height: 1.1rem;
}
.flervalg-gruppe-tittel {
  margin: 0;
  font-size: 0.82rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--tekst-svak);
}
.flervalg-velg-alle {
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 0.82rem;
  color: var(--aksent);
  cursor: pointer;
  text-decoration: underline;
}
.flervalg-velg-alle:hover { color: var(--aksent-lys); }
.flervalg-liste {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--kant);
  border-radius: 6px;
  padding: 0.35rem;
  display: flex;
  flex-direction: column;
}
.flervalg-rad {
  padding: 0.3rem 0.4rem;
  border-radius: 4px;
  gap: 0.55rem;
}
.flervalg-rad:hover { background: var(--flate-alt, rgba(0, 0, 0, 0.04)); }
.flervalg-rad input[type="checkbox"] { flex: none; }
.flervalg-etikett { flex: 1; min-width: 0; }
.flervalg-rad-av { opacity: 0.5; cursor: not-allowed; }
.flervalg-merknad { font-size: 0.78rem; color: var(--tekst-svak); flex: none; }
.flervalg-teller {
  margin-right: auto;
  align-self: center;
  font-size: 0.82rem;
  color: var(--tekst-svak);
}
.flervalg-teller-aktiv { color: var(--aksent); font-weight: 600; }

/* --------------------------------------------------------------------- */
/* Toast                                                                 */
/* --------------------------------------------------------------------- */
.toast-beholder {
  position: fixed;
  bottom: 1.25rem;
  right: 1.25rem;
  z-index: 200;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-width: 360px;
}
.toast {
  background: var(--flate);
  border-left: 4px solid var(--aksent);
  border-radius: var(--radius);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  padding: 0.7rem 0.9rem;
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  animation: toast-inn 0.18s ease-out;
}
.toast-info { border-left-color: var(--aksent); }
.toast-suksess { border-left-color: var(--gronn); }
.toast-feil { border-left-color: var(--rod); }
.toast-advarsel { border-left-color: var(--gul); }
.toast-tekst { flex: 1; font-size: 0.88rem; }
.toast-lukk { background: transparent; border: none; cursor: pointer; font-size: 1.1rem; line-height: 1; color: var(--tekst-svak); }
.toast-ut { opacity: 0; transform: translateX(10px); transition: all 0.2s; }
@keyframes toast-inn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }

/* --------------------------------------------------------------------- */
/* Faner                                                                 */
/* --------------------------------------------------------------------- */
.faner { margin-top: 0.5rem; }
.fane-nav { display: flex; gap: 0.25rem; border-bottom: 2px solid var(--kant); margin-bottom: 1.25rem; flex-wrap: wrap; }
.fane-knapp {
  background: transparent;
  border: none;
  padding: 0.6rem 1rem;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--tekst-svak);
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
}
.fane-knapp:hover { color: var(--aksent); }
.fane-knapp.aktiv { color: var(--aksent); font-weight: 600; border-bottom-color: var(--aksent); }

/* --------------------------------------------------------------------- */
/* Tilstander                                                            */
/* --------------------------------------------------------------------- */
.laster { padding: 2rem; text-align: center; color: var(--tekst-svak); }
.tom-tilstand { padding: 1.5rem; text-align: center; color: var(--tekst-svak); font-style: italic; }
.feil-tilstand { color: var(--rod); font-style: normal; }
.svak { color: var(--tekst-svak); }

.def-liste { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1rem; margin: 0; }
.def-liste dt { font-weight: 600; color: var(--tekst-svak); font-size: 0.85rem; }
.def-liste dd { margin: 0; }

.enkel-liste { list-style: none; margin: 0; padding: 0; }
.enkel-liste li { padding: 0.35rem 0; border-bottom: 1px solid var(--kant); }

/* --------------------------------------------------------------------- */
/* Dashbord                                                              */
/* --------------------------------------------------------------------- */
.tall-rad { display: flex; gap: 1rem; flex-wrap: wrap; }
.tall-boks {
  flex: 1;
  min-width: 150px;
  background: var(--flate);
  border: 1px solid var(--kant);
  border-top: 3px solid var(--aksent);
  border-radius: var(--radius);
  box-shadow: var(--skygge);
  padding: 0.95rem 1.1rem;
  text-align: left;
}
/* Fargekodede statuskort (topplinje-aksent) */
.tall-boks-aksent { border-top-color: var(--aksent); }
.tall-boks-gul { border-top-color: var(--gul); background: #fffdf4; }
.tall-boks-gronn { border-top-color: var(--gronn); background: #f4faf5; }
.tall-boks-fare { border-top-color: var(--rod); background: #fdf6f6; }
.tall-verdi { font-size: 2.1rem; font-weight: 600; font-family: var(--font-overskrift); color: var(--aksent-mork); line-height: 1.05; letter-spacing: -0.01em; }
.tall-etikett { font-size: 0.72rem; color: var(--tekst-svak); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; margin: 0 0 0.25rem; }
.status-fordeling { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.9rem; }
.status-fordeling-post { display: inline-flex; align-items: center; gap: 0.3rem; font-size: 0.85rem; }

.varsel-liste, .hendelse-liste { list-style: none; margin: 0; padding: 0; }
.varsel { display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0; border-bottom: 1px solid var(--kant); }
.varsel:last-child, .hendelse:last-child { border-bottom: none; }
.varsel-tekst { flex: 1; }
.varsel-kritisk .varsel-tekst { font-weight: 500; }
.hendelse { display: flex; align-items: center; gap: 0.7rem; padding: 0.45rem 0; border-bottom: 1px solid var(--kant); }
.hendelse-dato { font-variant-numeric: tabular-nums; color: var(--tekst-svak); font-size: 0.85rem; min-width: 6rem; }
.hendelse-tittel { flex: 1; }

.tall-ok { color: var(--gronn); font-weight: 600; }
.tall-noytral { color: var(--tekst); }
.tall-fare { color: var(--rod); font-weight: 600; }
.flagg-ikon { color: var(--rod); font-weight: 600; }

/* --------------------------------------------------------------------- */
/* Grupper / flagg / medlemmer                                           */
/* --------------------------------------------------------------------- */
.gruppe-liste { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; }
.gruppe-kort { margin: 0; }
.gruppe-hode { display: flex; align-items: center; justify-content: space-between; }
.gruppe-hode h3 { margin: 0; }
.gruppe-meta { color: var(--tekst-svak); font-size: 0.85rem; margin: 0.25rem 0; }
/* «Medlemmer» og «Materiell» er to rubrikker paa samme nivaa i gruppekortet,
   og skal se like ut. Marginen laa foer som en inline-stil paa den ene av dem;
   naar to overskrifter skal vaere like, kan den ene ikke baere sin egen. */
.gruppe-underhode {
  margin: 0.8rem 0 0.3rem;
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--tekst-svak); font-weight: 600;
}

/* Navnene STABLES, ett per linje. Som flytende rad brakk en gruppe paa aatte
   navn i en klump der oyet maatte lete etter hvor det ene sluttet og det neste
   begynte. `flex-start` holder brikkene tette rundt navnet i stedet for aa
   strekke dem over hele kortet. */
.medlem-liste {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0.25rem; margin: 0 0 0.6rem;
}
.medlem-merke, .bemanning-merke {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: #e7e7ea;
  border-radius: 12px;
  padding: 0.15rem 0.55rem;
  font-size: 0.82rem;
}
.medlem-fjern {
  background: transparent; border: none; cursor: pointer; color: var(--tekst-svak);
  font-size: 0.95rem; line-height: 1; padding: 0;
}
.medlem-fjern:hover { color: var(--rod); }

.flagg-liste { list-style: none; margin: 0; padding: 0; }
.flagg-post { display: flex; align-items: center; gap: 0.6rem; padding: 0.5rem 0; border-bottom: 1px solid var(--kant); }
.flagg-tekst { flex: 1; }
.flagg-dato { color: var(--tekst-svak); font-size: 0.82rem; }
.flagg-lukket { opacity: 0.55; }

/* --------------------------------------------------------------------- */
/* Leksjon / koblinger                                                   */
/* --------------------------------------------------------------------- */
.merke-samling { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0.5rem 0; }
.kobling-merke {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: #e7e7ea;
  border: 1px solid var(--kant-mork);
  border-radius: 12px;
  padding: 0.15rem 0.6rem;
  font-size: 0.82rem;
  color: var(--tekst);
  cursor: default;
}
button.kobling-merke, .klikkbar-merke { cursor: pointer; font-family: inherit; }
.kobling-merke-passiv { opacity: 0.7; }
/* Gruppenavnet i studentlista («Gruppe 2-2») brøt over to linjer inne i
   merket: kolonnen er smal, og tabellen gir heller ord enn bredde. Navnet er
   kort og skal leses i ett — kolonnen får bredden den trenger. */
.kol-gruppe .kobling-merke { white-space: nowrap; }
/* Interne vedlegg på en leksjon: merket «Internt» ved tittelen, så det er
   lett å se hva studentene IKKE får. */
.dok-tittel-linje { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; }
.merke-intern { background: #5b4a8a; color: #fff; }
/* Gruppekortets materiell, gruppert på kategori (Droner, Utstyr …). */
.gruppe-materiell { display: flex; flex-direction: column; gap: 0.45rem; }
.gruppe-materiell-tittel { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--tekst-svak); margin-bottom: 0.2rem; }
.kobling-merke-bekreftet { background: #e4f0e5; border-color: var(--gronn); color: #1b5e20; }
.kobling-merke-utkast { background: #fff5e0; border-color: var(--gul); color: #7a5200; }
/* Navn med et lite merke etter seg — «deg» på egen rad i instruktørlista.
   Merket skal aldri dytte navnet ut på to linjer i en smal kolonne. */
.navn-med-merke { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; }
.navn-med-merke .kobling-merke { font-size: 0.72rem; padding: 0.05rem 0.45rem; }
.kobling-liste { display: flex; flex-direction: column; gap: 0.4rem; }
.kobling-rad { display: flex; align-items: center; gap: 0.6rem; padding: 0.35rem 0; border-bottom: 1px solid var(--kant); }
.kobling-tekst { flex: 1; }
.tidsplan-tabell textarea { min-width: 8rem; }

/* --------------------------------------------------------------------- */
/* Samling / timeplan                                                    */
/* --------------------------------------------------------------------- */
.timeplan-okt-tabell td { vertical-align: middle; }
.brudd-varsel {
  background: #fff5e0;
  border: 1px solid var(--gul);
  border-radius: var(--radius);
  padding: 0.25rem 0.5rem;
  font-size: 0.82rem;
  color: #7a5200;
  margin-top: 0.35rem;
}
.brudd-varsel-stor { margin-top: 0.75rem; padding: 0.6rem 0.85rem; }
.brudd-varsel-stor ul { margin: 0.4rem 0 0; padding-left: 1.2rem; }
.bemanning-celle { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.bemanning-merke-hi { background: #eef6ff; border: 1px solid var(--aksent); }
.bemanning-rolle { color: var(--tekst-svak); font-size: 0.76rem; }
/* Generer timeplan fra mal (modal) */
.mal-valg-liste { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.85rem; }
.mal-valg { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.6rem 0.75rem; border: 1px solid var(--kant-mork); border-radius: var(--radius); cursor: pointer; }
.mal-valg input { margin-top: 0.2rem; }
.mal-valg-navn { font-weight: 600; }
.mal-valg-meta { color: var(--tekst-svak); font-size: 0.82rem; }
.mal-valg-beskrivelse { font-size: 0.85rem; margin-top: 0.25rem; color: var(--tekst); }
.generer-info { background: #e7e7ea; border-radius: var(--radius); padding: 0.5rem 0.75rem; font-size: 0.88rem; margin-bottom: 0.85rem; }
.forb-liste { list-style: none; margin: 0; padding: 0; }
/* `flex-start` og ikke `center`: teksten kan vaere flere linjer, og da sto
   pensummerket og radknappene midtstilt utenfor den i stedet for ved foerste
   linje. */
.forb-liste li { display: flex; align-items: flex-start; gap: 0.5rem; padding: 0.5rem 0; border-bottom: 1px solid var(--kant); }
/* `pre-wrap` MAA staa her. Teksten skrives i et TEKSTOMRAADE, saa den kan
   inneholde linjeskift, punkter og innrykk — men uten denne kollapset alt til
   en eneste lang linje, og en liste med fem forberedelser ble en sammenhengende
   setning. Dette var det ENESTE stedet forberedelsesteksten ble vist uten
   `pre-wrap`; `.okt-tekst`, `.ns-forb` og `.leksjon-tekst` har den alle.
   `min-width: 0` slik at et langt ord bryter i stedet for aa dra raden bred. */
.forb-tekst { flex: 1; min-width: 0; white-space: pre-wrap; }
.forb-pensum { flex: 0 1 auto; min-width: 0; color: var(--tekst-svak); font-size: 0.85rem; }
/* Radknappene skal staa i hoeyde med FOERSTE linje, ikke midt i teksten. */
.forb-liste li .rad-handlinger { flex: 0 0 auto; margin-left: auto; }

/* --------------------------------------------------------------------- */
/* Studieplan                                                            */
/* --------------------------------------------------------------------- */
.forklaring { display: flex; gap: 1.25rem; align-items: center; margin-bottom: 1rem; flex-wrap: wrap; font-size: 0.85rem; }
.forklaring-post { display: inline-flex; align-items: center; gap: 0.4rem; }
.forklaring-post .kobling-merke { width: 1.5rem; height: 1rem; padding: 0; }
.ikke-dekket-tekst { color: var(--rod); font-weight: 600; }
.studieplan-matrise td { vertical-align: top; }
/* Punktcelle: tekst til venstre, «+ Koble» skjøvet helt til høyre på samme linje. */
.matrise-punkt { display: flex; align-items: flex-start; gap: 0.75rem; }
.matrise-punkt-tekst { flex: 1 1 auto; }
/* .merke-samling (leksjon-/samling-/pensum-cellene) har margin-top: 0.5rem
   før første bobble — «+Koble»-knappen får samme forskyvning slik at den
   ikke sitter høyere enn boblene i nabocellene på samme rad. */
.matrise-verktoy { margin-left: auto; margin-top: 0.5rem; flex: 0 0 auto; }
/* «+ Koble»-knappen skal visuelt matche kobling-merke-boblene i leksjon-/
   samling-cellene i samme rad — samme boks-/tekststørrelse OG samme høyde.
   line-height settes eksplisitt og likt på begge (i stedet for hver sin
   nedarvede "normal"-verdi), ellers gir identisk padding/font-size likevel
   ulik bokshøyde. Skopet til studieplan-matrisen for å ikke endre
   kobling-merke andre steder i appen. */
.matrise-verktoy .knapp { padding: 0.15rem 0.6rem; font-size: 0.82rem; line-height: 1.4; }
.studieplan-matrise .kobling-merke { line-height: 1.4; }
.ikke-dekket-rad td:first-child, .ikke-dekket-rad td:nth-child(2) { color: var(--rod); }
.ikke-dekket-merke {
  display: inline-block;
  margin-left: 0.5rem;
  color: #fff;
  background: var(--rod);
  border-radius: 10px;
  padding: 0.05rem 0.5rem;
  font-size: 0.72rem;
  font-weight: 600;
}

/* --------------------------------------------------------------------- */
/* Rapporter                                                             */
/* --------------------------------------------------------------------- */
.rapport-kort .kort-innhold { overflow: visible; }
.rapport-verktoy { display: flex; align-items: flex-end; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; }
.rapport-felt { display: flex; flex-direction: column; gap: 0.2rem; font-size: 0.82rem; color: var(--tekst-svak); }
.rapport-forhaandsvis { overflow-x: auto; }

/* --------------------------------------------------------------------- */
/* Timeføringsrapporten                                                  */
/*                                                                       */
/* Gruppene sto rett på hverandre uten luft: .tf-gruppe og .tf-sum hadde  */
/* ingen CSS i det hele tatt, så sammendraget ble fire merkebobler på rad */
/* uten mellomrom og gruppene fløt sammen til én blokk.                   */
/* --------------------------------------------------------------------- */
.tf-total { margin-bottom: 1.4rem; }
.tf-gruppe + .tf-gruppe { margin-top: 1.6rem; padding-top: 1.4rem; border-top: 1px solid var(--kant); }
/* Gruppenavnet er inngangen når man skanner nedover en lang rapport. */
.tf-gruppe > .seksjon-tittel, .tf-total > .seksjon-tittel { margin-bottom: 0.5rem; }
/* Rutene er smalere her enn i instruktørtabellen: rapporten har fire, og de
   skal få plass ved siden av hverandre uten å bli like brede som et kort. */
.rapport-forhaandsvis .tf-ruter {
  grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
  max-width: 42rem;
}
/* «Min progresjon»: statusmerket med datoen under seg. Kolonnen holdes smal
   slik at kommentaren — den eneste cella med loepende tekst — faar resten. */
.progresjon-tabell .kol-status-dato { width: 9.5rem; }
.status-dato {
  margin-top: 0.2rem;
  font-size: var(--t-liten); color: var(--tekst-svak);
  white-space: nowrap;
}

.status-matrise { font-size: 0.82rem; }
.status-celle { text-align: center; }
.utskrift-tabell { border-collapse: collapse; width: 100%; }
.utskrift-tabell th, .utskrift-tabell td { border: 1px solid var(--kant-mork); padding: 0.4rem 0.55rem; }
.kun-utskrift-tittel { display: none; }

/* --------------------------------------------------------------------- */
/* Utskrift (leksjonsdokument i modal)                                   */
/* --------------------------------------------------------------------- */
.utskrift-dok { color: #000; }
.utskrift-tittelblokk { border-bottom: 2px solid var(--aksent); padding-bottom: 0.75rem; margin-bottom: 1rem; }
.utskrift-tittelblokk h1 { color: var(--aksent); }
.utskrift-meta { border-collapse: collapse; }
.utskrift-meta th { text-align: left; padding: 0.15rem 1rem 0.15rem 0; color: var(--tekst-svak); font-weight: 600; }
.utskrift-felt { margin-bottom: 1rem; }
.utskrift-felt h2 { font-size: 1rem; border-bottom: 1px solid var(--kant); padding-bottom: 0.2rem; }
.utskrift-felt p { white-space: pre-wrap; margin: 0.4rem 0; }

/* --------------------------------------------------------------------- */
/* Admin / info                                                          */
/* --------------------------------------------------------------------- */
.import-resultat { margin-top: 1rem; }
.info-boks { background: #e7e7ea; border-radius: var(--radius); padding: 0.85rem 1.1rem; margin-top: 1rem; font-size: 0.9rem; }
.info-boks h4 { margin-top: 0; }
.info-boks ol, .info-boks ul { margin: 0.4rem 0; padding-left: 1.3rem; }
.kode-blokk {
  background: var(--aksent-mork);
  color: #e6edf5;
  padding: 0.6rem 0.85rem;
  border-radius: var(--radius);
  font-family: "Consolas", "Menlo", monospace;
  font-size: 0.85rem;
  overflow-x: auto;
}

/* --------------------------------------------------------------------- */
/* Responsiv                                                             */
/* --------------------------------------------------------------------- */


/* --------------------------------------------------------------------- */
/* Ukeskalender                                                          */
/* --------------------------------------------------------------------- */
/* Visningsbryter (Kalender | Liste) */
.kal-bryter-wrap { margin-left: auto; }
.kal-bryter { display: inline-flex; border: 1px solid var(--kant-mork); border-radius: var(--radius); overflow: hidden; }
.kal-bryter-knapp {
  background: var(--flate); border: none; cursor: pointer; font-family: inherit;
  font-size: 0.85rem; padding: 0.35rem 0.8rem; color: var(--tekst-svak);
}
.kal-bryter-knapp + .kal-bryter-knapp { border-left: 1px solid var(--kant-mork); }
.kal-bryter-knapp:hover { background: #e7e7ea; color: var(--aksent); }
.kal-bryter-knapp.aktiv { background: var(--aksent); color: #fff; }

/* Ukesnavigasjon */
.kal-nav { display: flex; align-items: center; justify-content: center; gap: 0.6rem; margin-bottom: 0.75rem; }
.kal-nav-knapp {
  background: var(--flate); border: 1px solid var(--kant-mork); border-radius: var(--radius);
  cursor: pointer; font-size: 1.1rem; line-height: 1; padding: 0.2rem 0.6rem; color: var(--aksent);
}
.kal-nav-knapp:hover:not(:disabled) { background: #e7e7ea; }
.kal-nav-knapp:disabled { opacity: 0.35; cursor: not-allowed; }
.kal-nav-tittel { font-size: 0.95rem; color: var(--tekst); }
.kal-nav-datoer { color: var(--tekst-svak); font-weight: normal; }

/* Rutenett */
.kal-kalender {
  overflow-x: auto;
  border: 1px solid var(--kant);
  border-radius: var(--radius);
  background: var(--flate);
  /* Plass til den SISTE timeetiketten. Etikettene sentreres på timelinja med
     translateY(-0.55em), og den siste ligger på nederste linje — altså på
     selve underkanten av rutenettet. Halve tekstboksen hang dermed utenfor,
     og ti piksler overskudd er nok til at nettleseren legger på et loddrett
     rullefelt: kalenderen fikk en bitteliten rulling opp og ned selv om alt
     så ut til å få plass. Rullefeltet stjal i tillegg sytten piksler bredde,
     så dagkolonnene ble smalere enn de trengte å være.

     Overskuddet er målt til ti piksler. Verdien her er 1rem og ikke 0.75rem
     nettopp fordi den skal tåle at etiketten vokser — med 0.75rem sto det
     halvannen piksel igjen, og da er man én fontjustering fra å ha feilen
     tilbake uten å skjønne hvorfor.

     Merk at overflow-y IKKE kan settes til hidden her, slik .tl-ramme gjør.
     Kalenderen har ingen fast høyde, og når den ruller vannrett spiser det
     vannrette rullefeltet av høyden — da ville hidden klippet bort nederste
     time i stedet for å vise den. Riktig svar er å fjerne overskuddet. */
  padding-bottom: 1rem;
}
/* Ingen min-width: max-content — kolonnene skal krympe så alle dagene får
   plass på skjermen. Nedre grense settes av minmax() i samling.js; først da
   slår overflow-x på .kal-kalender inn. */
.kal-grid { display: grid; min-width: 0; }
.kal-hjorne { border-bottom: 1px solid var(--kant); border-right: 1px solid var(--kant); background: #e7e7ea; }
.kal-dag-hode {
  display: flex; flex-direction: column; align-items: center; gap: 0.05rem;
  padding: 0.45rem 0.5rem; background: #e7e7ea; color: var(--aksent-mork);
  border-bottom: 1px solid var(--kant); border-right: 1px solid var(--kant);
  position: sticky; top: 0; z-index: 3;
}
.kal-dag-navn { font-weight: 600; font-size: 0.85rem; }
.kal-dag-dato { font-size: 0.76rem; color: var(--tekst-svak); }
.kal-dag-hode.kal-helg { background: #e2e2e5; }

/* «Uten tidspunkt»-stripe */
.kal-gutter-merk {
  font-size: 0.68rem; color: var(--tekst-svak); text-align: right;
  padding: 0.3rem 0.4rem; border-bottom: 1px solid var(--kant); border-right: 1px solid var(--kant);
  background: #f0f0f1;
}
.kal-utentid {
  display: flex; flex-direction: column; gap: 0.25rem;
  padding: 0.3rem; border-bottom: 1px solid var(--kant); border-right: 1px solid var(--kant);
  background: #f0f0f1; min-height: 1.5rem;
}

/* Tidsakse (gutter) */
.kal-tid-gutter { position: relative; border-right: 1px solid var(--kant); }
.kal-tid-merke {
  position: absolute; right: 0.35rem; transform: translateY(-0.55em);
  font-size: 0.72rem; color: var(--tekst-svak); white-space: nowrap;
}

/* Dagkropp med timelinjer */
.kal-dag-kropp {
  position: relative; border-right: 1px solid var(--kant);
  background-image: repeating-linear-gradient(
    to bottom, transparent 0, transparent calc(100% - 1px), var(--kant) calc(100% - 1px), var(--kant) 100%);
}
.kal-dag-kropp.kal-helg { background-color: #f4f4f5; }

/* Øktblokk */
.kal-blokk {
  position: absolute; box-sizing: border-box; overflow: hidden;
  text-align: left; cursor: pointer; font-family: inherit;
  border: 1px solid; border-radius: 5px; padding: 0.2rem 0.35rem;
  display: flex; flex-direction: column; gap: 0.05rem; line-height: 1.2;
}
.kal-blokk:hover { box-shadow: 0 2px 6px rgba(20, 40, 70, 0.2); z-index: 4; }
.kal-blokk-leksjon {
  background: #eef6ff; border-color: var(--aksent-lys); color: var(--aksent-mork);
  border-left: 3px solid var(--aksent);
}
.kal-blokk-annet {
  background: #f0f1f3; border-color: var(--kant-mork); color: var(--tekst-svak);
  border-left: 3px solid var(--graa);
}
.kal-blokk-kompakt { position: static; }
.kal-blokk-tid { font-size: 0.68rem; font-weight: 600; opacity: 0.85; }
.kal-blokk-tittel { font-size: 0.76rem; font-weight: 600; }
.kal-blokk-sted { font-size: 0.72rem; opacity: 0.85; }
.kal-blokk-hi { font-size: 0.72rem; }
.kal-blokk-hi-merke { font-size: 0.64rem; font-weight: 600; opacity: 0.7; }
.kal-blokk-ovrige { color: var(--tekst-svak); }
.kal-blokk-markor { font-size: 0.68rem; opacity: 0.85; }
.kal-brudd { color: var(--rod); font-weight: 700; }

/* Øktredigering — seksjoner i modal */
.okt-seksjon { margin-bottom: 1.25rem; }
.okt-seksjon-tittel { font-size: 1rem; margin-bottom: 0.75rem; padding-bottom: 0.3rem; border-bottom: 1px solid var(--kant); }
/* Øverst i øktvinduet: hva vinduet gjelder, og knappen til leksjonen. */
.okt-intro { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1rem; flex-wrap: wrap; }
.okt-intro-tekst { margin: 0; flex: 1 1 18rem; }
.okt-intro .knapp[hidden] { display: none; }
.okt-underhode { font-size: 0.85rem; margin: 0.85rem 0 0.4rem; color: var(--tekst-svak); }
.okt-bemanning { margin-top: 0.5rem; }
.okt-bemanning-tom { color: var(--tekst-svak); font-style: italic; font-size: 0.85rem; }
.okt-bemanning-legg { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.6rem; flex-wrap: wrap; }
.okt-bemanning-velger { width: auto; min-width: 8rem; flex: 1 1 8rem; }
.okt-bemanning-hint { margin-top: 0.5rem; }

/* Utskrift: kalenderen egner seg ikke for print — bruk listevisningen. */
@media print {
  .kal-bryter-wrap, .kal-nav { display: none !important; }
  .kal-kalender { overflow: visible !important; border: none; }
}

/* Seleksjon */
/* «Rangér distrikt» plasseres på linje med bunnen av filtervelgerne. */
.sel-ranger-knapp { align-self: flex-end; }

/* Kommentar-kolonne: fast bredde, klipp med ellipse, klikk for utvid/rediger. */
.tabell td.kol-kommentar { width: 16rem; max-width: 16rem; }
.kommentar-celle { width: 100%; }
.kommentar-tekst {
  max-width: 16rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  border-radius: var(--radius);
  padding: 0.15rem 0.3rem;
  margin: -0.15rem -0.3rem;
}
.kommentar-tekst:hover { background: #e7e7ea; }
.kommentar-tom { color: var(--tekst-svak); font-style: italic; }
.kommentar-celle.kommentar-redigerer { white-space: normal; }
.kommentar-input {
  width: 100%;
  min-width: 14rem;
  font: inherit;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--kant);
  border-radius: var(--radius);
  resize: vertical;
  box-sizing: border-box;
}
.kommentar-knapper { display: flex; gap: 0.4rem; margin-top: 0.4rem; justify-content: flex-end; }

/* Inline-redigering i seleksjonstabellen — feltene ser subtile ut (usynlig
   ramme) til man peker/redigerer, så tabellen ikke blir en vegg av bokser. */
.inline-input {
  font: inherit;
  font-size: 0.85rem;
  padding: 0.15rem 0.3rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: transparent;
  color: var(--tekst);
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}
.inline-input:hover { border-color: var(--kant); background: var(--flate); }
.inline-input:focus { border-color: var(--aksent); background: var(--flate); outline: none; }
select.inline-input { cursor: pointer; }
.inline-number { max-width: 6rem; }
.inline-date { max-width: 9rem; }
.inline-bid { max-width: 7rem; text-transform: uppercase; }
.inline-kandidatnr { max-width: 4.5rem; text-transform: uppercase; }
/* Testbatteri: inputfeltet tar plassen, ↗-lenken ligger fast til høyre. */
.inline-url-celle { display: flex; gap: 0.25rem; align-items: center; }
.inline-url-celle .inline-url { flex: 1; min-width: 0; }
.inline-url-lenke {
  flex: none;
  text-decoration: none;
  color: var(--aksent);
  font-size: 0.95rem;
  line-height: 1;
  padding: 0.15rem;
}
.inline-url-lenke:hover { color: var(--aksent-lys); }
.inline-resultat { display: flex; gap: 0.3rem; align-items: center; }
.inline-resultat .inline-input { width: auto; }
.inline-resultat .inline-date { max-width: 8.5rem; }
.inline-checkbox { width: 16px; height: 16px; cursor: pointer; }

/* --- Seleksjonstabell: tydelige kolonner (skillelinjer, faste bredder) --- */
/* table-layout: fixed gjør at kolonnebreddene faktisk honoreres (ellers
   komprimerer nettleseren dem etter innhold). ALLE kolonner må ha eksplisitt
   width på header-cella. width:auto på tabellen gjør den nøyaktig så bred som
   summen; .tabell-wrap gir horisontal scroll på smale skjermer. */
/* min-width MAA vaere summen av kolonnebreddene under. Med table-layout:fixed
   og width:100% fordeler nettleseren den plassen som finnes over de oppgitte
   breddene — er min-width for lav, klemmes ALLE kolonnene proporsjonalt i
   stedet for at tabellen ruller. Datofeltet er flex:0 0 6rem og gir seg ikke,
   saa hele klemmen gikk ut over nedtrekkene: «Ikke bestaatt» havnet bak pila
   igjen selv om resultatkolonnen var kalibrert.
   Sto paa 66.8rem fra for de to delkolonnene fantes. Summen naa er 99.4rem. */
/* `min-width` MAA vaere summen av kolonnebreddene. Er den lavere, klemmes
   ALLE kolonnene proporsjonalt i stedet for at tabellen ruller — og felt
   med fast flex-grunnlag gir ikke etter, saa hele klemmen gaar ut over
   nedtrekkene. 99,4rem + 3,2rem for «Innkalt» = 102,6rem, + 1rem da
   Distrikt gikk fra tekst til nedtrekk = 103,6rem. */
.sel-tabell-holder table.tabell { table-layout: fixed; width: 100%; min-width: 103.6rem; }
.sel-tabell-holder table.tabell th,
.sel-tabell-holder table.tabell td {
  border-right: 1px solid var(--kant);
  vertical-align: middle;
  padding: 0.35rem 0.3rem;
  overflow: hidden;
  font-size: 0.85rem;
}
/* Overskriftene brytes over flere linjer. Da kan kolonnene være så smale som
   innholdet krever i stedet for så brede som ordet i toppen — det er der
   bredden ellers går tapt på «Seleksjonsresultat» og «Kandidatnummer». */
.sel-tabell-holder table.tabell th {
  white-space: normal;
  line-height: 1.15;
  vertical-align: bottom;
}
.sel-tabell-holder table.tabell .inline-input { font-size: 0.85rem; padding: 0.2rem 0.3rem; }
.sel-tabell-holder table.tabell th:last-child,
.sel-tabell-holder table.tabell td:last-child { border-right: none; }
/* Vekslende radfarge + tydeligere hover for lettere linjelesing. */
.sel-tabell-holder table.tabell tbody tr:nth-child(even) { background: rgba(29, 45, 61, 0.025); }
.sel-tabell-holder table.tabell tbody tr:hover { background: #eaeef2; }

/* Breddene er FORHOLDSTALL: tabellen er table-layout: fixed med width: 100%,
   så alt normaliseres til holderens bredde. Verdiene under er hver kolonnes
   målte minimum (innhold + cellepadding), og min-width over er summen — da er
   ingenting for trangt på den smaleste skjermen.
   Navn og Kommentar står med vilje UTEN bredde: i fixed layout deler kolonner
   uten oppgitt bredde all overskuddsbredde likt mellom seg, mens de øvrige blir
   stående på sin oppgitte bredde. På en bred skjerm er det nettopp de to som
   har nytte av mer plass — de andre har innhold med fast lengde, og ekstra
   bredde der blir bare tomrom. På en smal skjerm er det også de to som tåler å
   bli klemt: et navn brekker over to linjer, en kontroll blir uleselig. */
/* Kolonnebreddene er satt etter måling av hva innholdet FAKTISK trenger, ikke
   etter gjetning. Utgangspunktet var skjevt: navnet fikk 85 px og brøt seg over
   tre linjer, mens flere kolonner var for smale til å vise sin egen overskrift.

   Navnet er det man skanner nedover og får derfor plass til én linje (det
   lengste, «Charlotte Torgersen Bråttum», måler 157 px). Resultatkolonnen er
   bred fordi den holder TO kontroller — nedtrekksmeny og dato — ikke fordi den
   er sløsete. */
.sel-tabell-holder .kol-sel-navn { width: 12.5rem; min-width: 12.5rem; }
.sel-tabell-holder .kol-sel-bid { width: 4.8rem; }
.sel-tabell-holder .kol-sel-kandidatnr { width: 4.4rem; }
.sel-tabell-holder .kol-sel-testbatteri { width: 7rem; }
/* Nok til aa SE at en lenke er lagt inn, ikke til aa lese hele. Feltet var
   2.7rem, som ga 31px innmat - tre og en halv bokstav. */
/* 4.2rem holdt for ren tekst, men ikke for et nedtrekk: pila spiser ~20px, og
   de fire lengste distriktskodene er paa fire tegn. MAALT: et <select> med
   «MRPD» krever 64px naturlig bredde og fikk 53 - koden ble klippet. 5.2rem
   gir 78px celle og 68px nedtrekk. Summen under er oppdatert med det samme
   rem-et. */
.sel-tabell-holder .kol-sel-distrikt { width: 5.2rem; }
/* Fast bredde, ikke auto: er tabellen bredere enn beholderen, blir en
   auto-kolonne klemt til null. Kommentaren kan ekspanderes i raden. */
/* Fikk de 1.75rem som ble til overs da Samlet-nedtrekket ble halvert.
   Kommentaren er fritekst og har mest nytte av plassen. */
.sel-tabell-holder .kol-kommentar { width: 10.75rem; max-width: 10.75rem; }
.sel-tabell-holder .kol-sel-status { width: 7.6rem; }
/* Nedtrekket er halvert: 52px -> 26px, maalt paa 1440px. Datofeltet staar
   fast paa 6rem, saa hele reduksjonen tas av velgeren. Verdien leses av
   fargen og av title-teksten - og paa rader med delregistreringer er
   dette et merke, ikke et nedtrekk. */
.sel-tabell-holder .kol-sel-resultat { width: 8.65rem; }
/* Samlet er som regel et MERKE (avledet), ikke et nedtrekk. Bredden er
   derfor satt av datofeltet, ikke av «Ikke bestaatt». */
/* .inline-resultat er en flex-boks der bare select faar flex-grunnlag. Et
   merke uten egen regel kollapser derfor til 0px ved siden av datofeltet,
   som staar paa flex:0 0 6rem og ikke gir seg. */
/* ---- Standardraden paa telefon ---------------------------------------
   Én linje per rad, samme form som seleksjonslista (Retning B). Kort per
   rad ble maalt til 300-430px hoyde; en klasseliste paa tretti ble ni tusen
   piksler rulling. Dette er 56px. */
.tabell-kort-tett { gap: 0; }
.tabell-kort-tett .tabell-kort-post {
  border: 0; border-bottom: 1px solid var(--kant); border-radius: 0;
  box-shadow: none; background: var(--flate); padding: 0;
}
.tabell-kort-tett .tabell-kort-post:first-child { border-top: 1px solid var(--kant); }
.tabell-kort-tett .tabell-kort-post.klikkbar:active { background: #e7e7ea; }

.std-rad {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0 0.75rem; min-height: 56px;
}

/* ---- Studentens arbeidskrav paa telefon ---------------------------------
   Raden maa baere FEM ting: oppgaven, statusen, fristen, veien til oppgaven
   (lenke/fil) og innleveringen. Paa en linje ble tittelen 150 px og fristen
   falt ut. To linjer holder den fortsatt kompakt - oppgave og status oeverst,
   frist og handlinger under - og gir knappene en flate man treffer. */
.ak-rad {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.75rem; min-height: 56px;
}
/* Tittel over frist, som en enhet. De hoerer sammen — hva det er, og naar. */
.ak-rad-tekst { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
/* `flex: 0 0 auto`, IKKE `1 1 0`. Forelderen er en flekskolonne, saa
   flekseaksen er LODDRETT — en basis paa 0 kollapser hoyden, og tittelen ble
   0 px hoy og usynlig mens `getBoundingClientRect().width` fortsatt sa 198.
   `min-width: 0` maa staa for at ellipsen skal virke i en fleksboks. */
.ak-rad-tittel {
  flex: 0 0 auto; min-width: 0; max-width: 100%;
  font-size: var(--t-normal); font-weight: 500; color: var(--tekst);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Statusen staar MIDTSTILT i sin egen kolonne, mellom teksten og knappene.
   Laa den oeverst til hoeyre, flyttet den seg vannrett fra rad til rad etter
   hvor bredt merket var — «Godkjent» mot «Levert — til vurdering» — og
   kolonnen lot seg ikke lese nedover. Den faar krympe foer tittelen gjoer
   det; et merke som brekker over to linjer sprenger radhoeyden. */
/* Andre linje: merket forrest, saa fristen. */
.ak-rad-linje2 { display: flex; align-items: center; gap: 0.45rem; min-width: 0; }
.ak-rad-merke { flex: 0 0 auto; display: inline-flex; align-items: center; }
/* Merket er mindre her enn i tabellen: det staar sammen med fristen paa en
   hjelpelinje, ikke som en egen kolonne, og skal ikke rope hoyere enn
   tittelen over. */
.ak-rad-merke .merke { font-size: var(--t-mikro); padding: 0.1rem 0.4rem; }
.ak-rad-merke .merke { display: inline-block; }

.ak-rad-meta {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: baseline; gap: 0.5rem;
  font-size: var(--t-liten); color: var(--tekst-svak);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Midtprikk som skille, samme som hjelpelinjene ellers i appen. Sto de bare
   med `gap`, laa de riktig visuelt, men limte seg sammen for en skjermleser
   og ved kopiering: «Frist 01.09.2026Levert #1». */
.ak-rad-levert::before { content: '·'; margin-right: 0.5rem; color: var(--kant-mork); }
.ak-rad-levert { color: var(--tekst-svak); }

.ak-rad-handlinger {
  flex: 0 0 auto; display: flex; align-items: center; gap: 0.1rem;
  margin-right: -0.5rem;         /* flatene henger utenfor radens padding */
}
.ak-ikon {
  display: flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 40px;
  color: var(--aksent-lys); background: transparent; border: 0;
  text-decoration: none; cursor: pointer; padding: 0;
}
.ak-ikon:hover { color: var(--aksent-mork); }
/* Leveringsknappen er den ene handlingen som endrer noe. Den skal skille seg
   fra kildene, som bare aapner noe. */
.ak-ikon-lever { color: #fff; background: var(--aksent); min-width: 44px; }
.ak-ikon-lever:hover { background: var(--aksent-mork); color: #fff; }
/* Samme bredde som leveringsknappen, uten aa vaere en knapp. */
.ak-ikon-tom { min-width: 44px; cursor: default; pointer-events: none; }

/* Handlinger som ikke gir mening paa en telefon. Utskrift er den ene: ingen
   har skriver der, og knappen tok plass i en fot der «Lukk» er det man
   trenger. */
@media (max-width: 780px) { .kun-skrivebord { display: none !important; } }
.std-rad-tekst { flex: 1 1 0; min-width: 0; }
.std-rad-id {
  font-size: 0.95rem; font-weight: 500; color: var(--tekst);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.std-rad-hjelp {
  font-size: 0.76rem; color: var(--tekst-svak);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Statusen staar til hoyre og faar krympe foer teksten gjor det - et merke
   som brekker over to linjer sprenger radhoyden. */
.std-rad-status {
  flex: 0 1 auto; min-width: 0; text-align: right;
  font-size: 0.82rem; color: var(--tekst-svak);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 45%;
}
.std-rad-status .merke { display: inline-block; }
.std-rad-pil { flex: 0 0 14px; color: var(--graa); font-size: 1.2rem; line-height: 1; }

/* ---- Instruktørkortet på telefon ----------------------------------------
   `.std-rad` er en flexRAD, og med fem handlingsknapper pluss to hele
   tabellceller (puljemerker, timeføringssammendrag) ble alt klemt: navnet
   klippet, merkene presset til 55 px med ett ord per linje. Kortet stabler
   i stedet, og hver bolk får hele bredden. */
.instr-kort {
  flex-direction: column; align-items: stretch; gap: 0.5rem;
  padding: 0.7rem 0.75rem;
}
.instr-kort-navn { min-width: 0; font-weight: 600; }
/* Handlingene på egen rad nederst, skilt med en strek. Fem ikoner er 216 px
   med mobilens trykkflater — delte de linje med navnet, satt navnet igjen
   med ~100 px. */
.instr-kort-handlinger {
  display: flex; justify-content: flex-end;
  padding-top: 0.5rem; border-top: 1px solid var(--kant);
}
.instr-kort-handlinger .rad-handlinger { flex-wrap: wrap; justify-content: flex-end; }
.instr-kort-bolk { min-width: 0; }
/* Tabellcellene inni er bygget for en kolonne. På kortet skal de bruke hele
   bredden og bryte i stedet for å krympe. */
.instr-kort .instr-pulje-celle { align-items: flex-start; }
.instr-kort .merke-samling { flex-wrap: wrap; }
.instr-kort .tf-celle { flex-wrap: wrap; row-gap: 0.5rem; }
.instr-kort .tf-tall { flex: 1 1 10rem; }

/* Felt som bærer en kontroll — en utfoldingspil, en knapp — tegnes som node
   under hjelpelinja i stedet for å flates til tekst. Se standardKort. */
.std-rad-kontroller {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  margin-top: 0.3rem; font-size: 0.82rem;
}

/* Utvidelsespanelet i KORTMODUS. I tabellmodus er panelet en søskenrad med
   colspan; her ligger det inne i kortet, og skal se ut som en forlengelse av
   det — ikke som et nytt kort. Full bredde av kortet, skilt med en strek. */
.kort-utvidelse {
  margin-top: 0.5rem; padding-top: 0.5rem;
  border-top: 1px solid var(--kant);
}
.tabell-kort-post:has(> .kort-utvidelse) { background: var(--flate); }
/* ---- Pensumraden paa telefon --------------------------------------------
   Avkryssingen forrest, tittelen i midten, kildene som ikoner til hoyre. */
.pensum-rad { gap: 0.4rem; }

/* Boksen er 1,05rem (~16px). Flata rundt gjoer den treffbar med tommelen uten
   aa gjoere selve boksen stor og klumpete. */
.pensum-lest-flate {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 44px;
  margin-left: -0.5rem;          /* trykkflata skal ikke skyve teksten innover */
  cursor: pointer;
}

/* Lest post tones ned — samme signal som `tr.rad-lest` gir i tabellen. */
.std-rad.rad-lest .std-rad-id { color: var(--tekst-svak); font-weight: 400; }

.pensum-kilder {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 0.15rem;
  margin-right: -0.4rem;         /* ikonflatene henger utenfor radens padding */
}
.pensum-ikon {
  display: flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 44px;
  color: var(--aksent-lys);
  text-decoration: none;
}
.pensum-ikon:hover { color: var(--aksent-mork); }
/* Plassholder for rader uten kilde, saa ikonkolonnen ikke vingler. */
.pensum-kilder-tom {
  display: flex; align-items: center; justify-content: center;
  min-width: 40px; min-height: 44px;
  color: var(--graa);
}

/* Tittelceller som tegnes av en `render` (pensum bruker `.matrise-punkt`)
   havner som et BLOKKBARN inne i `.std-rad-id`. Forelderens
   `text-overflow: ellipsis` gjelder bare dens EGEN inline-tekst, ikke et
   blokkbarn - tittelen ble derfor hardt kappet midt i ordet, uten ellipse:
   «Kompendium, observasjon og formidlingstjene». Avkortingen maa staa paa
   barnet, og `min-width: 0` maa til for at et fleksbarn i det hele tatt
   skal faa lov aa bli smalere enn innholdet sitt. */
.std-rad-id .matrise-punkt { min-width: 0; }
.std-rad-id .matrise-punkt-tekst {
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  overflow-wrap: normal; word-break: normal;
}
.std-rad-handling { flex: 0 0 auto; display: flex; gap: 0.3rem; }
.std-rad-handling .ikon-knapp { min-height: 40px; min-width: 40px; }

/* ---- Retning B: prioritert liste paa telefon --------------------------
   Én linje per person. Lista er ikke kort, saa den slipper kortrammen -
   .tabell-kort-post nulles ut for denne beholderen. */
/* «Innkalles»: bestod del 1, men beskjeden er ikke gitt. Eneste tilstanden i
   lista som krever en handling av deg, saa den skal se ut som noe annet enn
   resultatprikkene ved siden av. */
.sel-liste-venter {
  flex: 0 0 auto;
  font-size: var(--t-mikro); font-weight: 600; letter-spacing: 0.02em;
  color: #3a2c00; background: var(--gul);
  padding: 0.1rem 0.35rem; white-space: nowrap;
}

.sel-liste { gap: 0; }
.sel-liste .tabell-kort-post {
  border: 0; border-top: 0; border-bottom: 1px solid var(--kant);
  box-shadow: none; background: var(--flate);
  padding: 0; border-radius: 0;
}
.sel-liste .tabell-kort-post:first-child { border-top: 1px solid var(--kant); }
.sel-liste .tabell-kort-post.klikkbar:active { background: #e7e7ea; }

.sel-liste-rad {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0 0.75rem; min-height: 56px;
}
.sel-liste-navn { flex: 1 1 0; min-width: 0; }
.sel-liste-etternavn {
  font-size: 0.95rem; font-weight: 500; color: var(--tekst);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sel-liste-distrikt { font-size: 0.76rem; color: var(--tekst-svak); }
.sel-liste-prikker { flex: 0 0 auto; display: flex; align-items: center; gap: 0.35rem; }
.sel-liste-pil { flex: 0 0 16px; color: var(--graa); font-size: 1.2rem; line-height: 1; }

/* Prikkene. Samlet skiller seg med en ring, ikke med en annen farge - fargen
   er allerede opptatt av utfallet. */
.sel-prikk {
  width: 18px; height: 18px; border-radius: 10px; flex: 0 0 18px;
  display: inline-block;
}
.sel-prikk-sum { outline: 2px solid var(--aksent-mork); outline-offset: 1px; }
.sel-prikk-gronn { background: var(--gronn); }
.sel-prikk-rod { background: var(--rod); }
.sel-prikk-gul { background: var(--gul); }
.sel-prikk-graa { background: var(--graa); }

/* Tegnforklaringen finnes fordi fargen ikke faar baere betydningen alene.
   Over telefonbredde staar kolonnene med tekst, og da er den bare stoy. */
.sel-liste-tegnforklaring { display: none; }
@media (max-width: 780px) {
  .sel-liste-tegnforklaring {
    display: flex; flex-wrap: wrap; gap: 0.75rem;
    padding: 0.7rem 0.75rem; font-size: 0.76rem; color: var(--tekst-svak);
  }
  .sel-tf { display: flex; align-items: center; gap: 0.3rem; }
  .sel-tf .sel-prikk { width: 12px; height: 12px; flex-basis: 12px; }
}

.sel-tabell-holder .samlet-merke { flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; text-align: center; }

/* Fargede nedtrekk for del 1 og del 2. Samme palett som merkene, slik at en
   rad leses likt enten verdien staar i et merke eller i et nedtrekk. Fargen
   settes av statusFarge() i ui.js - ikke av et eget kart her.
   Pila tegnes av nettleseren og arver color, saa den foelger med. */
.sel-tabell-holder select.velger-gronn { background: var(--gronn); color: #fff; border-color: var(--gronn); }
.sel-tabell-holder select.velger-rod   { background: var(--rod);   color: #fff; border-color: var(--rod); }
.sel-tabell-holder select.velger-gul   { background: var(--gul);   color: #3a2c00; border-color: var(--gul); }
.sel-tabell-holder select.velger-graa  { background: var(--graa);  color: #fff; border-color: var(--graa); }
/* Alternativlista aapnes av nettleseren og arver ikke fargen paa en lesbar
   maate - tving den tilbake til vanlig tekst paa mork bakgrunn. */
.sel-tabell-holder select[class*="velger-"] option { background: #fff; color: var(--tekst, #1d2d3d); }
/* Del 1 og del 2 er BARE en velger - seleksjonen har én dato, og den staar i
   Samlet-kolonnen. Bredden er satt av den lengste teksten, «Ikke bestaatt»,
   pluss pila. Uten datofeltet trenger de under halvparten av Samlet. */
.sel-tabell-holder .kol-sel-del { width: 6.8rem; }
/* Bare en avkryssing — trenger ikke mer enn overskriften «Innkalt». */
.sel-tabell-holder .kol-sel-informert { width: 3.2rem; text-align: center; }
.sel-tabell-holder td.kol-sel-informert { text-align: center; }
.sel-tabell-holder .kol-sel-gyldig { width: 6.1rem; }
.sel-tabell-holder .kol-sel-rang { width: 3.4rem; }
.sel-tabell-holder .kol-sel-innst { width: 3.6rem; }
.sel-tabell-holder .kol-sel-tilbud { width: 3rem; text-align: center; }
.sel-tabell-holder .kol-sel-svar { width: 5.4rem; }
/* Navnet skal ikke brytes — er det for langt, kappes det med ellipse og hele
   navnet ligger i tittelen. Tre linjers radhøyde gjorde lista uleselig. */
.sel-tabell-holder td.kol-sel-navn { white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
/* Begge radknappene må få plass — 3,7rem kappet dem i alle 24 radene. */
.sel-tabell-holder .kol-handling { width: 4.4rem; }

/* Tall høyrejustert for skanning; avkryssing midtstilt. */
.sel-tabell-holder td.kol-sel-tall .inline-input { text-align: right; }
.sel-tabell-holder td.kol-sel-tilbud { text-align: center; }
/* Kommentar-cella tilpasses den faste kolonnebredden. */
.sel-tabell-holder .kommentar-tekst { max-width: none; }
.sel-tabell-holder .kommentar-input { min-width: 0; }
/* Resultat-cellen: nedtrekk og dato side om side på ÉN linje.
   Datofeltet må ha plass til «04.08.2026» PLUSS kalenderikonet — under ca.
   6 rem legger ikonet seg oppå de siste sifrene. Nedtrekket er avstemt mot
   innholdet: pil og innramming tar 31 px, så «Bestått» (41 px) krever 72 og
   «Ikke møtt» 82. Bredden er satt til 82 — «Ikke bestått» (96) er den eneste
   som forkortes, og hele teksten står i hjelpeteksten. */
.sel-tabell-holder .inline-resultat { flex-wrap: nowrap; gap: 0.25rem; }
.sel-tabell-holder .inline-resultat .inline-input { min-width: 0; }
/* Nedtrekket tar ALT som er igjen etter datofeltet. Med fast bredde ble det
   stående et tomrom til høyre for datoen på skjermer bredere enn kolonnens
   minimum — og tomrommet vokste med oppløsningen. Nå vokser nedtrekket i
   stedet, så «Ikke bestått» får bedre plass jo bredere skjermen er. */
.sel-tabell-holder .inline-resultat select.inline-input { flex: 1 1 auto; }
/* Datofeltet trenger aldri mer enn dette: dato pluss kalenderikon. */
.sel-tabell-holder .inline-resultat .inline-date { flex: 0 0 6rem; max-width: none; }
/* Samme minimum for «Gyldig til» — den hadde nøyaktig samme klipping. */
.sel-tabell-holder td.kol-sel-gyldig .inline-date { width: 100%; max-width: none; }
/* Stramt ikon: gir noen piksler tilbake til sifrene i begge datofeltene. */
.sel-tabell-holder .inline-date::-webkit-calendar-picker-indicator {
  margin-left: 0; padding: 0; opacity: 0.55;
}

/* Øktmodal: seksjonshode med tittel til venstre og slett-knapp til høyre. */
.okt-seksjon-hode {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 0.5rem;
}
.okt-seksjon-hode .okt-seksjon-tittel { margin: 0; }

/* Årshjul: uthev hendelser som hører til den valgte puljen når alle vises,
   slik at «egne» skiller seg fra de andre puljenes aktiviteter. */
.arshjul-egen-pulje { font-weight: 600; color: var(--aksent-mork); }

/* Backup — statuslinje og sammenleggbare innstillinger på Admin */
.backup-status {
  border-left: 3px solid var(--aksent);
  background: rgba(29, 45, 61, 0.03);
  padding: 0.6rem 0.85rem;
  margin-bottom: 0.9rem;
}
.backup-innstillinger { margin-top: 1rem; }
.backup-innstillinger > summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--aksent);
  padding: 0.35rem 0;
}

/* Rangering (dra-og-slipp) */
.rang-innhold { display: flex; flex-direction: column; gap: 0.5rem; }
.rang-distrikt { font-weight: 600; margin: 0; }
.rang-felter { display: flex; gap: 1.25rem; flex-wrap: wrap; }
.rang-feltvalg { display: inline-flex; align-items: center; gap: 0.35rem; cursor: pointer; }
.rang-forklaring {
  margin: 0;
  font-size: 0.85rem;
  color: var(--tekst-svak);
  background: #f0f0f1;
  border: 1px solid var(--kant);
  border-radius: var(--radius);
  padding: 0.5rem 0.7rem;
}
.rang-liste { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 0.25rem; }
.rang-rad {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.6rem;
  border: 1px solid var(--kant);
  border-radius: var(--radius);
  background: var(--flate);
  cursor: grab;
}
.rang-rad.rang-drar { opacity: 0.5; }
.rang-rad.rang-over { border-color: var(--aksent); border-top-width: 3px; }
.rang-nr {
  min-width: 1.5rem;
  font-weight: 700;
  color: var(--tekst-svak);
  text-align: right;
}
.rang-navn { flex: 1 1 auto; }
.rang-knapper { display: inline-flex; gap: 0.2rem; }
.rang-tom { color: var(--tekst-svak); font-style: italic; padding: 0.5rem 0; }

/* Tidligere søkere */
.sel-tidligere { margin-top: 1.5rem; border-top: 1px solid var(--kant); padding-top: 0.75rem; }
.sel-tidligere-hode {
  font-weight: 600;
  cursor: pointer;
  padding: 0.35rem 0;
  list-style-position: inside;
}
.sel-tidligere-hode:hover { color: var(--aksent); }
.tidligere-utlopt { color: var(--rod); font-weight: 600; }

/* Dato mangler */
.dato-mangler {
  color: #c62828;
  font-weight: 600;
  font-size: 0.85em;
}

/* --------------------------------------------------------------------- */
/* Dashbord — statuskort + tidslinje mot eksamen (1c)                    */
/* --------------------------------------------------------------------- */
/* «Kom i gang» — oppsettsveiviser, står øverst til oppsettet er fullført. */
.komigang-kort { border-left: 3px solid var(--aksent); }
.komigang-liste { list-style: none; margin: 0.6rem 0 0; padding: 0; display: flex; flex-direction: column; }
.komigang-steg {
  display: flex; align-items: flex-start; gap: 0.7rem;
  padding: 0.5rem 0.2rem; border-bottom: 1px solid var(--kant);
}
.komigang-steg:last-child { border-bottom: none; }
/* Haken har fast bredde, slik at titlene står på samme venstrekant enten
   steget er gjort eller ikke — ellers hopper lista sidelengs nedover. */
.komigang-hake {
  flex: 0 0 1.3rem; text-align: center; font-weight: 700;
  color: var(--gronn); line-height: 1.4;
}
.komigang-tekst { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; min-width: 0; }
.komigang-tittel { font-weight: 600; }
.komigang-hjelp { font-size: 0.85rem; color: var(--tekst-svak); }
.komigang-gjort .komigang-tittel { color: var(--tekst-svak); font-weight: 400; }
.komigang-neste { background: var(--flate); }

.status-kort-rad {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-bottom: 1.25rem;
}
@media (max-width: 900px) { .status-kort-rad { grid-template-columns: repeat(2, 1fr); } }

.tidslinje-meta { color: var(--tekst-svak); font-size: 0.85rem; margin-bottom: 0.35rem; }
.tidslinje { position: relative; height: 120px; margin-top: 0.25rem; }
/* Tegneflata. Alt innhold plasseres i PROSENT av DENNE, ikke av .tidslinje,
   slik at et merke paa 0 % eller 100 % faar hele seg selv innenfor kanten.
   Innrykket maa vaere minst halve bredden av det breieste merket paa aksen
   (eksamenspunktet, 17 px). */
.tidslinje-plot { position: absolute; top: 0; bottom: 0; left: 10px; right: 10px; }
.tidslinje-akse { position: absolute; left: 0; right: 0; top: 58px; height: 1px; background: var(--kant-mork); }
.tidslinje-progresjon { position: absolute; left: 0; top: 57px; height: 3px; background: var(--aksent); }
.tidslinje-idag { position: absolute; top: 30px; bottom: 20px; width: 1px; background: var(--aksent-lys); }
.tidslinje-idag-merke {
  position: absolute; top: 8px; transform: translateX(-50%);
  font-size: 0.6rem; letter-spacing: 0.1em; font-weight: 700;
  color: #fff; background: var(--aksent); padding: 1px 7px; border-radius: 3px; white-space: nowrap;
}
.tidslinje-idag-merke.ved-start { transform: translateX(0); }
.tidslinje-idag-merke.ved-slutt { transform: translateX(-100%); }
.tidslinje-punkt {
  position: absolute; top: 54px; width: 9px; height: 9px;
  background: var(--aksent); transform: translateX(-50%); border-radius: 2px;
}
.tidslinje-punkt.fremtid { background: var(--flate); border: 1.5px solid var(--aksent); }
.tidslinje-punkt.stor { width: 15px; height: 15px; top: 51px; background: var(--aksent-mork); }
.tidslinje-punkt.stor.fremtid { background: var(--flate); border: 1.5px solid var(--aksent-mork); }
/* Fysiske samlinger: bjelke der bredden = varighet. Venstre kant på startdato
   (ingen translateX). Minstebredde gjør en endagssamling synlig som liten blokk. */
.tidslinje-bjelke {
  position: absolute; top: 51px; height: 15px; min-width: 10px;
  background: var(--aksent-mork); border-radius: 2px;
}
.tidslinje-bjelke.fremtid { background: var(--flate); border: 1.5px solid var(--aksent-mork); }
/* Flerdags Teams/forberedelse: samme høyde og farge som punktene deres. */
.tidslinje-bjelke.liten { top: 54px; height: 9px; min-width: 9px; background: var(--aksent); }
.tidslinje-bjelke.liten.fremtid { background: var(--flate); border-color: var(--aksent); }
.tidslinje-punkt.eksamen { width: 17px; height: 17px; top: 50px; background: var(--aksent-mork); }
/* --tl-dx er forskyvningen dashboard.js regner ut. Den legges INNI
   transformen i stedet for å røre `left`, slik at den virker uansett om
   etiketten er sentrert (-50%) eller høyrestilt (-100%, eksamen). */
.tidslinje-etikett {
  position: absolute; top: 30px; transform: translateX(calc(-50% + var(--tl-dx, 0px)));
  font-size: 0.66rem; line-height: 1.15; text-align: center; color: var(--tekst-svak); white-space: nowrap;
}
/* Etikettene fordeles vannrett av dashboard.js når de ellers ville overlappet:
   avstanden blir omtrentlig, men alle blir stående på SAMME høyde. Den skrå
   streken viser hvilket punkt en forskjøvet etikett hører til. */
.tidslinje-streker {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 1;
}
.tidslinje-streker line { stroke: var(--kant-mork); stroke-width: 1; }
/* Forskjøvne etiketter hadde `color: var(--tekst)` — nær sort — for å være
   «litt tydeligere» når teksten ikke står rett under punktet sitt. Resultatet
   var to tekstfarger om hverandre i samme tidslinje, avhengig av om etiketten
   tilfeldigvis måtte flyttes. Det er den skrå streken som viser tilhørigheten;
   fargen trengs ikke, og skillet leses som en betydningsforskjell som ikke
   finnes. Alle etiketter er nå `--tekst-svak`, som de uforskjøvne alltid var. */
/* Fysiske samlinger og eksamen er tyngre milepaeler enn en Teams-oekt. */
.tidslinje-etikett.stor { font-weight: 700; color: var(--aksent-mork); letter-spacing: 0.03em; }
/* `line-height` MAA staa her. Uten den arvet datoen 1.45 fra `html, body`, og
   linjeboksen ble hoeyere enn geometrien var regnet for - paa telefon stakk
   den 6 px ut av en boks med `overflow: hidden`, og nedre halvdel av sifrene
   ble klippet bort. Soesterregelen over har alltid hatt 1.15; at denne manglet
   den var en forglemmelse, ikke et valg. */
.tidslinje-etikett-dato {
  position: absolute; top: 70px; transform: translateX(calc(-50% + var(--tl-dx, 0px)));
  font-size: 0.6rem; line-height: 1.15; color: var(--tekst-svak); white-space: nowrap; text-align: center;
}
.tidslinje-etikett.eksamen, .tidslinje-etikett-dato.eksamen {
  transform: translateX(calc(-100% + var(--tl-dx, 0px))); text-align: right;
}

/* Statuskort — hjelpetekst under tallet */
.tall-hjelp { font-size: 0.78rem; color: var(--tekst-svak); margin-top: 0.35rem; }

/* Dashbord-hode: kicker + tittel + datometa */
.dash-hode { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; flex-wrap: wrap; }
.dash-eyebrow { font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--aksent); font-weight: 600; margin-bottom: 0.15rem; }
.dash-hode .side-tittel { margin: 0; }
.dash-meta { color: var(--tekst-svak); font-size: 0.82rem; }

/* Varsler + kommende side om side */
.dash-kol-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
.dash-kol-2 > .kort { margin-bottom: 0; }
@media (max-width: 900px) { .dash-kol-2 { grid-template-columns: 1fr; } }

/* Innholdsflate — svakt blueprint-rutenett bak kortene */
.innhold {
  background-image:
    linear-gradient(rgba(31, 58, 95, 0.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(31, 58, 95, 0.035) 1px, transparent 1px);
  background-size: 26px 26px;
}

/* Sidefelt — logo, grupper og nummererte lenker */
.sidefelt-logo { flex-direction: column; align-items: flex-start; gap: 0.15rem; }
.logo-tittel { font-weight: 700; font-size: 1.1rem; letter-spacing: 0.02em; color: #fff; line-height: 1.1; }
.logo-undertittel { font-size: 0.6rem; letter-spacing: 0.13em; text-transform: uppercase; color: rgba(234, 240, 247, 0.55); }
.nav-seksjon { margin-top: 0.15rem; }
.nav-gruppe-tittel {
  padding: 0.5rem 1.25rem 0.15rem; font-size: 0.6rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: rgba(234, 240, 247, 0.45); font-weight: 600;
}
.nav-nr {
  display: inline-block; min-width: 1.6rem; font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.03em; color: rgba(234, 240, 247, 0.45);
}
.nav-lenke.aktiv .nav-nr { color: #fff; }
.sidefelt-bunn { margin-top: auto; padding: 0.6rem 1.25rem; border-top: 1px solid rgba(255, 255, 255, 0.12); }
.sidefelt-versjon { font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(234, 240, 247, 0.4); }

/* Toppfelt — versal etikett, statusmerke og dato */
.pulje-etikett { text-transform: uppercase; letter-spacing: 0.08em; font-size: 0.72rem; font-weight: 600; color: var(--tekst-svak); }
.toppfelt-hoyre { display: flex; align-items: center; gap: 1rem; }
.topp-dato { color: var(--tekst-svak); font-size: 0.85rem; }

/* Ugraderte (flate) hjørner — teknisk uttrykk som i designet. --radius er 0,
   så dette nuller kun de stedene som hadde egne, hardkodede radier. */
.merke, .modal, .toast, .kobling-merke, .medlem-merke, .bemanning-merke,
.kal-blokk, .info-boks, .generer-info, .rang-rad, .rang-forklaring,
.auth-boks, .advarsel-boks, .brudd-varsel,
.ikke-dekket-merke, .kal-kalender, .mal-valg { border-radius: 0; }

/* --------------------------------------------------------------------- */
/* Låste puljer — fryst historikk                                        */
/* --------------------------------------------------------------------- */
/* Å låse en fullført pulje er en NORMALTILSTAND, ikke en feil. Banneret
   bruker derfor husets rolige aksentfarge — bevisst IKKE rødt/gult som
   .advarsel-boks og .brudd-varsel, som signaliserer at noe er galt. */
.laast-banner {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  background: color-mix(in srgb, var(--aksent) 10%, var(--flate));
  border: 1px solid var(--kant-mork);
  border-left: 3px solid var(--aksent);
  border-radius: var(--radius);
  padding: 0.7rem 0.95rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
}
.laast-banner-ikon { font-size: 1.05rem; line-height: 1.35; flex: 0 0 auto; }
.laast-banner-tekst { flex: 1 1 auto; min-width: 0; }
.laast-banner-merknad { margin-top: 0.25rem; }
.laast-banner-hjelp { margin-top: 0.3rem; color: var(--tekst-svak); font-size: 0.85rem; }
.laast-banner ul { margin: 0.35rem 0 0; padding-left: 1.2rem; }
.laast-banner li { margin-bottom: 0.15rem; }
.laast-banner-handling { margin-top: 0.6rem; }

/* 🔒-merke i tabellrader (nøytralt, ikke et statusmerke i farge). */
.laast-merke {
  display: inline-block;
  margin-left: 0.45rem;
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--kant-mork);
  border-radius: var(--radius);
  background: var(--flate);
  color: var(--tekst-svak);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}
.pulje-navn-celle { display: inline-flex; align-items: center; flex-wrap: wrap; }

/* Liste over berørte låste puljer i bekreftelsesdialogen. */
.laast-puljeliste { margin: 0.5rem 0; padding-left: 1.2rem; }
.laast-puljeliste li { margin-bottom: 0.2rem; }

/* Skrivebeskyttet skjema (fryst leksjonsinnhold): feltene skal fortsatt være
   fullt lesbare — kun tydelig inaktive. Ingen nedtoning av tekstfargen. */
.skjema-lest .skjema-input[readonly],
.skjema-lest .skjema-input:disabled,
.celle-input[readonly] {
  background: var(--bg);
  color: var(--tekst);
  border-style: dashed;
  cursor: default;
  opacity: 1;
}

/* --------------------------------------------------------------------- */
/* Studieløp — grafisk tidslinje (én rad per aktivitet, kronologisk)      */
/* --------------------------------------------------------------------- */
/* Posisjonene settes i prosent fra JavaScript. Bredden styres her: sporet
   fyller det som er igjen etter etikettkolonnen, og under min-bredden ruller
   rammen sidelengs i stedet for å presse aksen sammen. */
/* Hoydene paa maanedsbaandet og «I DAG»-merket staar som variabler fordi TRE
   regler maa henge sammen: baandet, merket, og den roede streken som skal naa
   helt opp til merket. Streken ligger i radoverlegget, som begynner UNDER
   baandet — uten et felles tall ville den enten stoppet 17 px for tidlig
   eller stukket forbi, og ingen av delene kan ses i koden alene. */
.tl-rute { --tl-etikett: 248px; --tl-mnd-hoyde: 32px; --tl-merke-hoyde: 16px; min-width: 620px; }
/* Regelen som sto her for <=720px var DOEDKODE: telefonblokka lenger ned i
   fila setter samme variabel med samme spesifisitet og matcher hele <=780px,
   saa den vant alltid. Fjernet framfor aa staa og se ut som om den gjorde noe. */

.tl-status { font-size: 0.88rem; margin-bottom: 0.6rem; }
.tl-status .svak { color: var(--tekst-svak); }

.tl-ramme {
  /* overflow-y må settes eksplisitt: med bare overflow-x: auto regner
     nettleseren om overflow-y til auto og reserverer plass til et loddrett
     rullefelt som aldri trengs. */
  overflow-x: auto; overflow-y: hidden;
  border: 1px solid var(--kant);
  background: var(--flate);
}

/* Felles geometri: etikettkolonne med fast bredde, spor som tar resten. */
.tl-mnd-rad, .tl-rad { display: flex; align-items: stretch; }
.tl-hjorne, .tl-etikett {
  position: sticky; left: 0; z-index: 5; flex: none; width: var(--tl-etikett);
  border-right: 1px solid var(--kant-mork); background: var(--flate);
}
.tl-spor { position: relative; flex: 1; min-width: 0; }

/* Månedsbånd.
   Baandet er hoyere enn maanedsteksten trenger, fordi «I DAG» skal staa OVER
   teksten og ikke ved siden av den. Merket kan ikke legges oppaa rammekanten:
   `.tl-ramme` maa ha `overflow-y: hidden` (ellers reserverer nettleseren
   plass til et loddrett rullefelt som aldri trengs), og alt over kanten ville
   blitt klippet bort. Loesningen er aa gi plass INNENFOR: merket oeverst,
   maanedsteksten under. */
.tl-mnd-rad { height: var(--tl-mnd-hoyde); border-bottom: 1px solid var(--kant-mork); }
.tl-mnd {
  position: absolute; top: 12px; height: 20px; line-height: 20px;
  font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--tekst-svak); padding-left: 4px; white-space: nowrap; overflow: hidden;
  border-left: 1px solid var(--kant);
}

/* Radene. Rekkefølgen nedover er tidsrekkefølgen. */
.tl-rader { position: relative; }
.tl-rad { height: 23px; cursor: pointer; }
.tl-rad:nth-child(even) { background: rgba(31, 58, 95, 0.035); }
.tl-rad:hover { background: color-mix(in srgb, var(--aksent) 12%, transparent); }

.tl-etikett {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0 0.5rem 0 0.55rem; font-size: 0.76rem; overflow: hidden;
}
/* Sticky celle må ha egen flate, ellers skinner bjelkene gjennom ved rulling. */
.tl-rad:nth-child(odd) .tl-etikett { background: var(--flate); }
.tl-rad:nth-child(even) .tl-etikett { background: #e6e7ea; }
.tl-rad:hover .tl-etikett { background: #dde5ee; }

.tl-prikk { flex: none; width: 8px; height: 8px; background: var(--aksent); }
/* Den korte datoformen finnes bare på telefon — se media-spørringen. */
.dato-kort { display: none; }
.tl-dato {
  flex: none; width: 88px; color: var(--tekst-svak);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.tl-tittel { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-rad:hover .tl-tittel { color: var(--aksent); text-decoration: underline; }

.tl-bjelke {
  position: absolute; top: 50%; transform: translateY(-50%);
  height: 12px; min-width: 6px; background: var(--aksent);
  border: 1px solid var(--aksent); box-sizing: border-box; z-index: 2;
}

/* Gjennomførte poster tones ned; det som ligger foran er det man planlegger
   etter. Pågående post får en tydelig ring. */
.tl-rad.passert .tl-bjelke, .tl-rad.passert .tl-prikk { background: var(--graa); border-color: var(--graa); }
.tl-rad.passert .tl-tittel, .tl-rad.passert .tl-dato { color: var(--tekst-svak); }
.tl-rad.pagar .tl-bjelke { box-shadow: 0 0 0 2px color-mix(in srgb, var(--aksent) 40%, transparent); }
.tl-rad.pagar .tl-tittel { font-weight: 600; }

/* Kategorifarger. Samlinger er husfargen; frister og eksamen skal stikke ut. */
.tl-k-seleksjon .tl-bjelke, .tl-k-seleksjon .tl-prikk { background: var(--gul); border-color: #c98a00; }
.tl-k-frist .tl-bjelke, .tl-k-frist .tl-prikk { background: var(--rod); border-color: var(--rod); }
.tl-k-arbeidskrav .tl-bjelke, .tl-k-arbeidskrav .tl-prikk { background: #6a5192; border-color: #6a5192; }
.tl-k-eksamen .tl-bjelke, .tl-k-eksamen .tl-prikk { background: var(--gronn); border-color: var(--gronn); }
.tl-k-annet .tl-bjelke, .tl-k-annet .tl-prikk { background: var(--graa); border-color: #7c7c80; }
.tl-k-samling .tl-bjelke, .tl-k-samling .tl-prikk { background: var(--aksent-mork); border-color: var(--aksent-mork); }
/* Samlingstypene skilles innbyrdes: fysisk er tyngst, teams er en enkeltdag,
   forberedelse er instruktørenes egen tid og tegnes skravert. */
.tl-t-teams .tl-bjelke, .tl-t-teams .tl-prikk { background: var(--aksent); border-color: var(--aksent); }
.tl-t-forberedelse .tl-bjelke {
  background: repeating-linear-gradient(45deg, var(--flate), var(--flate) 3px, var(--aksent) 3px, var(--aksent) 5px);
  border-color: var(--aksent);
}

/* Overlegg for rutenett og «I DAG»: dekker alle radene, forskjøvet forbi
   etikettkolonnen slik at prosentene treffer samme akse som bjelkene. */
.tl-overlegg { position: absolute; left: var(--tl-etikett); right: 0; top: 0; bottom: 0; pointer-events: none; }
.tl-rutelinje { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--kant); z-index: 1; }
.tl-rutelinje.nytt-ar { background: var(--kant-mork); }
/* Streken foeres helt opp til underkanten av «I DAG»-merket. Overlegget den
   ligger i begynner under maanedsbaandet, saa den maa trekkes oppover forbi
   baandet og dets 1px underkant, og stoppe der merket slutter. Da leses de to
   som EN markoer i stedet for som et merke og en strek som ikke moetes.
   Rammens `overflow-y: hidden` klipper ikke: -17px er fortsatt innenfor. */
.tl-idag {
  position: absolute; bottom: 0; width: 1px; background: var(--rod); z-index: 1;
  top: calc(var(--tl-merke-hoyde) - var(--tl-mnd-hoyde) - 1px);
}
.tl-idag-merke {
  position: absolute; top: 0; transform: translateX(-50%); z-index: 4;
  /* Fast hoyde, ikke bare padding: streken over regner med tallet, og en
     hoyde som foelger skriftmetrikk ville flyttet seg med fonten. */
  height: var(--tl-merke-hoyde); box-sizing: border-box;
  display: flex; align-items: center;
  font-size: 0.6rem; letter-spacing: 0.1em; font-weight: 700; color: #fff;
  background: var(--rod); padding: 0 6px; white-space: nowrap;
}

/* Poster uten dato — de har ingen plass på aksen, men må ikke bli usynlige. */
.tl-udatert { display: flex; align-items: baseline; gap: 0.5rem; margin-top: 0.6rem; flex-wrap: wrap; }
.tl-udatert-tittel { font-size: 0.82rem; color: var(--tekst-svak); }

@media print {
  .tl-ramme { overflow: visible; }
}

/* --------------------------------------------------------------------- */
/* Tilganger                                                             */
/* --------------------------------------------------------------------- */
.tilgang-kategori { display: flex; flex-direction: column; gap: 0.6rem; }
.tilgang-kat-hode {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.tilgang-kat-hode strong { font-size: 1.05rem; margin-right: 0.5rem; }
.tilgang-omfang { display: flex; align-items: center; gap: 0.6rem; }
.tilgang-omfang .skjema-input { max-width: 22rem; }
.tilgang-kolonner {
  display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); gap: 1.25rem;
}
.tilgang-underhode {
  margin: 0 0 0.35rem; font-size: 0.78rem; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--tekst-svak);
}
.tilgang-niva { min-width: 7rem; }
@media (max-width: 900px) { .tilgang-kolonner { grid-template-columns: 1fr; } }

/* Merke i toppfeltet når man ser appen som en bestemt bruker. */
.identitet-merke {
  background: var(--aksent); color: #fff; border-radius: 999px;
  padding: 0.2rem 0.7rem; font-size: 0.82rem; font-weight: 600; white-space: nowrap;
}
/* Merket er inngangen til «Min profil». Det skal se ut som noe man kan trykke
   på — men beholde formen sitt, siden plasseringen er det som gjør det
   gjenkjennelig. */
.identitet-knapp {
  border: 0; font-family: inherit; cursor: pointer;
}
.identitet-knapp:hover { filter: brightness(1.15); }
.identitet-knapp:focus-visible { outline: 2px solid var(--aksent); outline-offset: 2px; }

/* «Min profil»: kontoopplysningene står som fakta over skjemaet. */
.profil-konto { margin-bottom: 1.1rem; }

/* Feltavhukinger på Tilganger-siden. */
.felt-kol { white-space: nowrap; }
.felt-vipp { margin-right: 0.4rem; }
.felt-teller { font-size: 0.78rem; }
.felt-rad.skjult { display: none; }
.felt-rad > td { background: var(--flate-2, rgba(0,0,0,0.03)); padding: 0.6rem 0.8rem; }
.felt-liste {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 0.15rem 1rem;
}
.felt-snarveier { margin-top: 0.5rem; display: flex; gap: 0.8rem; }
/* Tekstknapp uten ramme — brukes til «Felter»-vippen og Alle/Ingen. */
.lenke-knapp {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--aksent); font-size: 0.82rem; font-family: inherit;
}
.lenke-knapp:hover { text-decoration: underline; }

/* Klikkbare milepæler i tidslinjen. */
.tidslinje-klikkbar { cursor: pointer; }
.tidslinje-klikkbar:hover { filter: brightness(1.15); }
.tidslinje-etikett.tidslinje-klikkbar:hover,
.tidslinje-etikett.stor.tidslinje-klikkbar:hover { text-decoration: underline; }
.tidslinje-klikkbar:focus-visible { outline: 2px solid var(--aksent); outline-offset: 2px; }

/* Lest-markering på pensum. */
.kol-lest { width: 2.6rem; text-align: center; }
.lest-boks { cursor: pointer; width: 1.05rem; height: 1.05rem; }
/* Lest vises med dempet tekst og avhuking — ikke gjennomstreking. Streken
   leses som «utgått/slettet», ikke som «gjort», og gjør teksten tyngre å lese
   nettopp der studenten skal kunne lese den om igjen. */
tr.rad-lest > td { color: var(--tekst-svak); }
tr.rad-lest .lenke { color: var(--tekst-svak); }
/* I forberedelseslistene: samme signal, uten tabell. */
li.lest-post { color: var(--tekst-svak); }

/* --------------------------------------------------------------------------
   Neste samling (dashbord)

   FIRE teksttyper, ikke flere. Kortet hadde elleve kombinasjoner av størrelse,
   vekt og farge, og da forsvinner rangeringen mellom dem:
     .ns-tittel  samlingens navn
     .ns-meta    dato, sted, tema, klokkeslett — alt sekundært
     .ns-merke   versaletikett som deler kortet i bolker
     (arvet)     brødtekst for forberedelser og pensum

   `.ns-meta` og `.ns-merke` er IKKE lenger private for dette kortet:
   fristkortet bruker dem også. Navnet er arvet fra der de oppsto. Trenger et
   tredje sted samme vokabular, bruk disse framfor å lage en fjerde skala som
   ligger 0,02 rem unna — det var nettopp den nesten-likheten som fikk
   fristkortet til å se feil ut uten at man så hvorfor.
   -------------------------------------------------------------------------- */
.neste-samling { font-size: 0.88rem; line-height: 1.45; }
/* Møtelenken i øktlinja. Liten, men ikke dempet — den skal kunne treffes raskt
   rett før undervisningen starter. */
.ns-motelenke { font-size: 0.82rem; white-space: nowrap; }

/* --------------------------------------------------------------------------
   Fristkortet — det den som ikke forvalter fristen får i stedet for skjemaet.
   Tre bolker i fast rekkefølge: hva skal gjøres, hva trengs, hvor står jeg.

   Kortet har INGEN egen skriftskala. Første utgave hadde det, med verdier som
   lå like ved siden av de etablerte — 0.9 mot 0.875, 0.7 mot 0.6875, 600 mot
   700 — og nettopp fordi de var nesten like, leste det som at noe var galt
   uten at man så hva. Bolktitler bruker `.ns-merke`, sekundærtekst `.ns-meta`
   og lenker `.lenke`, altså de samme som «Neste samling» og leksjonssiden.
   Bare avstandene er egne.
   -------------------------------------------------------------------------- */
.frist-topp { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.75rem; }
.frist-bolk { margin-top: 1.1rem; }
.frist-post { padding: 0.2rem 0; }
/* Opphavet er sekundært: man skal se ÉN liste over hva som trengs, og først i
   andre rekke hvor det kommer fra. Bare avstanden er egen — fargen og
   størrelsen kommer fra `.ns-meta`, som står ved siden av i markupen. */
.frist-kilde { margin-left: 0.4rem; }
.frist-oppgave { margin: 0.2rem 0 0; white-space: pre-wrap; }

/* Koblingsseksjonen nederst i «Rediger hendelse». Den ligger UNDER skjemaet og
   ikke i rutenettet, fordi den oppfører seg annerledes: hver knapp åpner en
   dialog som lagrer med én gang, mens feltene over venter på «Lagre». Streken
   over er hele markeringen av det skillet — samme strek som .ns-hode bruker.

   Ingen egen skriftskala her heller. Bolktitlene er `.ns-merke`, tellingene
   `.ns-meta`, ledeteksten `.skjema-ledetekst` — de samme som ellers. */
.hend-koblinger { margin-top: 1.1rem; padding-top: 0.85rem;
  border-top: 1px solid var(--kant); }
.hend-koblinger > .skjema-ledetekst { margin-bottom: 0.6rem; }
.hend-koblinger > p { margin: 0.5rem 0 0; }
.hend-kobling {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; flex-wrap: wrap;
}
.hend-kobling + .hend-kobling { margin-top: 0.7rem; }
/* .ns-merke har egen bunnmargin for bruken i «Neste samling»; her står
   tellingen rett under og skal ligge tett. */
.hend-kobling .ns-merke { margin-bottom: 0.1rem; }

.ns-tittelrad { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ns-tittel {
  font-size: 1rem; font-weight: 600; color: var(--tekst);
  text-decoration: none;
}
a.ns-tittel:hover { text-decoration: underline; }

.ns-meta { color: var(--tekst-svak); font-size: 0.82rem; }
.ns-hode .ns-meta { margin-top: 0.15rem; }

.ns-merke {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--tekst-svak); margin-bottom: 0.3rem;
}

.ns-bolk + .ns-bolk { margin-top: 0.75rem; }
.ns-hode + .ns-bolk,
.ns-hode + .ns-dager { margin-top: 0.85rem; padding-top: 0.75rem;
  border-top: 1px solid var(--kant); }
.ns-bolk + .ns-dager { margin-top: 0.85rem; padding-top: 0.75rem;
  border-top: 1px solid var(--kant); }
/* Pensumbolken står UNDER timeplanen og får sin egen strek, på samme måte som
   timeplanen får en mot forberedelsene over den. */
.ns-dager + .ns-bolk { margin-top: 0.85rem; padding-top: 0.75rem;
  border-top: 1px solid var(--kant); }

.ns-liste { margin: 0; padding-left: 1.1rem; }
.ns-liste li { margin: 0.1rem 0; }
/* Avkryssingen erstatter kulepunktet framfor å komme i tillegg til det. */
.ns-liste li:has(.lest-boks) { list-style: none; margin-left: -1.1rem;
  display: flex; align-items: baseline; gap: 0.4rem; }

.ns-okt + .ns-okt { margin-top: 0.5rem; }
/* Tid i egen kolonne, resten av økta i den andre. Forberedelsesteksten ligger
   i samme kolonne som tittelen og trenger derfor ikke noe eget innrykk. */
.ns-okt { display: grid; grid-template-columns: auto 1fr; column-gap: 0.5rem;
  align-items: baseline; }
/* Brytes framfor å klemmes: tittel, sted og møtelenke på én linje blir for
   mye på en telefon, og uten wrap ville de tre skviset hverandre i stedet. */
.ns-oktlinje { display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; }
.ns-tid { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Prikken skiller stedet fra tittelen uten å koste en egen linje. */
.ns-sted::before { content: '·'; margin-right: 0.35rem; opacity: 0.7; }
/* Leksjonsnavnet åpner kortet. Samme uttrykk som korttittelen over: arver
   fargen og understrekes først ved peker, så dagseddelen ikke blir en vegg
   av blå lenker. */
.ns-leksjonlenke { color: inherit; text-decoration: none; cursor: pointer; }
.ns-leksjonlenke:hover,
.ns-leksjonlenke:focus-visible { text-decoration: underline; }
.ns-forb { margin: 0.15rem 0 0.15rem 0; white-space: pre-wrap; color: var(--tekst);
  font-style: italic; }

/* Pensum hører til dagen over og står i SAMME kolonne som timeplanen, så
   sammenhengen er synlig når to dager vises ved siden av hverandre. Streken
   skiller det fra øktene uten å gjøre det til et eget kort. */
.ns-dagpensum { border-top: 1px solid var(--kant); padding-top: 0.6rem; }

/* Valget om å ta leksjonen med når en økt slettes. Skilt visuelt fra
   koblingslistene over: de FORTELLER hva som skjer, denne SPØR. */
.slett-leksjonsvalg {
  margin-top: 0.9rem; padding-top: 0.75rem;
  border-top: 1px solid var(--kant);
}
.slett-leksjonsvalg .skjema-hjelp { margin-top: 0.35rem; }

.ns-dager { display: grid; grid-template-columns: 1fr; gap: 1rem; }
.ns-dager-2 { grid-template-columns: 1fr 1fr; }
.ns-dager-2 > .ns-bolk + .ns-bolk {
  margin-top: 0; border-left: 1px solid var(--kant); padding-left: 1rem;
}
@media (max-width: 780px) {
  .ns-dager-2 { grid-template-columns: 1fr; }
  .ns-dager-2 > .ns-bolk + .ns-bolk {
    border-left: 0; padding-left: 0; margin-top: 0.75rem;
    border-top: 1px solid var(--kant); padding-top: 0.75rem;
  }
}

/* --------------------------------------------------------------------------
   Øktsammendrag (modalen studenten får når hen klikker en økt i timeplanen)

   Hver del har sin egen ramme. Uten den rant alt sammen til én lang tekst:
   klassene som skulle skille bolkene hadde ingen regler i det hele tatt.
   -------------------------------------------------------------------------- */
.okt-sammendrag { display: flex; flex-direction: column; gap: 0.65rem; }

.okt-bolk {
  border: 1px solid var(--kant);
  border-radius: 6px;
  padding: 0.65rem 0.8rem;
  background: var(--flate);
}

.okt-bolk-hode {
  margin: 0 0 0.4rem;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--tekst-svak);
}

.okt-tekst { margin: 0; white-space: pre-wrap; line-height: 1.5; }

/* Fakta-boksen: etikett og verdi på rad, tydelig skilt uten egen overskrift. */
.okt-fakta { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem 1rem; }
.okt-fakta > div { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.okt-etikett {
  font-size: 0.68rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--tekst-svak);
}

/* Pensum står tidlig og skal være lett å skanne. Avkryssingen erstatter
   kulepunktet framfor å komme i tillegg til det. */
.okt-pensum { margin: 0; padding-left: 1.1rem; }
.okt-pensum li { margin: 0.15rem 0; }
.okt-pensum li:has(.lest-boks) {
  list-style: none; margin-left: -1.1rem;
  display: flex; align-items: baseline; gap: 0.45rem;
}

.okt-tomt { margin: 0; color: var(--tekst-svak); }

@media (max-width: 560px) {
  .okt-fakta { grid-template-columns: 1fr 1fr; }
}

/* Pensumkolonnen i leksjonsoversikten. Titlene er lange, så merkene kuttes
   med ellipse og full tittel ligger i tooltipen. */
.kol-pensum { max-width: 22rem; }
.merke-samling-tett { margin: 0; gap: 0.25rem; }
/* Lar ett langt, ubrytelig ord dele seg framfor å tvinge kolonnen bred. */
.kol-bryt { overflow-wrap: anywhere; }

/* Gjennomgangslista etter puljekopiering: dette er punkter man skal LESE, ikke
   en oppramsing man skanner forbi. Egen linje per punkt, med luft. */
.kopi-merknader { margin: 0.4rem 0 0; padding-left: 1.1rem; }
.kopi-merknader li { margin: 0.3rem 0; font-size: 0.9rem; }

/* --------------------------------------------------------------------- */
/* Sikkerhetskopi: varsler og gjenopprettingsprøve                        */
/*                                                                       */
/* Dommen står øverst og i klartekst. En kopi ingen har prøvd å åpne er   */
/* en antakelse, og det skal man se uten å lete.                         */
/* --------------------------------------------------------------------- */
.backup-varsler { margin-bottom: 1rem; }
.backup-varselliste { margin: 0; padding-left: 1.1rem; }
.backup-varselliste li { margin: 0.3rem 0; font-size: 0.9rem; }
.backup-varsel-kritisk { color: var(--rod); font-weight: 600; }
.backup-varsel-advarsel { color: #7a5200; }
.backup-dom {
  margin: 0 0 0.8rem; padding: 0.6rem 0.8rem; font-size: 0.9rem;
  border: 1px solid var(--kant); border-left: 4px solid var(--kant-mork);
  background: var(--flate);
}
.backup-dom-suksess { border-left-color: var(--gronn); }
.backup-dom-fare { border-left-color: var(--rod); }

/* --------------------------------------------------------------------- */
/* «Min progresjon» — studentens egen fremdrift                           */
/* --------------------------------------------------------------------- */
.progresjon-ruter { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); max-width: 44rem; }
/* Setningen som sier hva som GJENSTÅR. Tallene over sier hvor man er; denne
   sier hva som skal gjøres, og skal derfor ha mer vekt enn en hjelpetekst. */
.progresjon-status {
  margin: 0 0 1.2rem; padding: 0.6rem 0.8rem;
  border-left: 4px solid var(--aksent); background: var(--flate);
  font-size: 0.95rem;
}

/* De tre tabellene — Arbeidskrav, Oppmøte og Eksamen — er tre kort under
   hverandre, og skal leses som én oversikt. Med fri kolonnebredde regnet
   nettleseren fordelingen ut per tabell, av innholdet i nettopp den: «Status»,
   «Status» og «Resultat» startet på hvert sitt sted, og øyet måtte finne
   statuskolonnen på nytt for hvert kort.
   Fast oppsett med samme to første bredder løser det. Kolonne 1 er alltid HVA
   raden gjelder, kolonne 2 alltid statusen — resten deler det som blir igjen,
   og kan gjerne være ulik: den bærer detaljer, ikke sammenlikningen. */
   Bredden er MÅLT, ikke gjettet: det lengste navnet («Statsluftfarteksamen
   (Luftfartstilsynet)») krever 231 px av 1121, og det bredeste statusmerket
   99 px. 28 % og 14 % gir begge god margin uten å etterlate en halv tabell
   tomt ved siden av «Del 1». */
.progresjon-tabell { table-layout: fixed; width: 100%; }
.progresjon-tabell th:nth-child(1), .progresjon-tabell td:nth-child(1) { width: 28%; }
.progresjon-tabell th:nth-child(2), .progresjon-tabell td:nth-child(2) { width: 14%; }
/* Merket skal ikke brytes selv om kolonnen er fast. */
.progresjon-tabell td:nth-child(2) .merke { white-space: nowrap; }
/* Lange kravnavn og kommentarer bryter framfor å dytte tabellen bredere. */
.progresjon-tabell td { overflow-wrap: anywhere; }

@media (max-width: 700px) {
  /* På smal skjerm er 42 % til navnet for lite; da gir vi slipp på det faste
     oppsettet og lar innholdet bestemme igjen. */
  .progresjon-tabell { table-layout: auto; }
  .progresjon-tabell th, .progresjon-tabell td { width: auto !important; }
}

/* --------------------------------------------------------------------- */
/* Overføringsindikator (opp- og nedlasting)                              */
/*                                                                        */
/* Dekker sida med vilje: så lenge en fil er underveis skal det ikke gå an */
/* å starte den samme overføringen en gang til. Den ligger over vanlige    */
/* modaler, fordi den startes FRA en av dem.                              */
/* --------------------------------------------------------------------- */
.overforing-overlay { z-index: 1200; }
.overforing-boks { width: min(28rem, 92vw); text-align: left; }
.overforing-fil {
  font-size: 0.9rem; color: var(--tekst-svak); margin-bottom: 0.8rem;
  overflow-wrap: anywhere;
}
.overforing-stolpe {
  height: 0.6rem; background: var(--kant); overflow: hidden;
  border-radius: var(--radius);
}
.overforing-stolpe-fyll {
  height: 100%; width: 0; background: var(--aksent);
  transition: width 0.15s linear;
}
/* Ukjent total: stolpen kan ikke si hvor langt det er igjen, så den beveger
   seg i stedet for å lyve om en prosent. */
.overforing-ukjent {
  width: 35% !important; animation: overforing-glid 1.1s ease-in-out infinite;
}
@keyframes overforing-glid {
  0% { margin-left: 0; } 50% { margin-left: 65%; } 100% { margin-left: 0; }
}
/* Siste byte er sendt, men serveren krypterer og konverterer fortsatt. */
.overforing-arbeider {
  animation: overforing-puls 1.2s ease-in-out infinite;
}
@keyframes overforing-puls { 50% { opacity: 0.45; } }
.overforing-tall {
  margin-top: 0.45rem; font-size: 0.9rem; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.overforing-advarsel {
  margin: 0.8rem 0 0; padding: 0.5rem 0.7rem; font-size: 0.85rem;
  background: var(--flate); border-left: 3px solid var(--gul); color: #7a5200;
}
@media (prefers-reduced-motion: reduce) {
  .overforing-ukjent, .overforing-arbeider { animation: none; }
  .overforing-stolpe-fyll { transition: none; }
}

/* --------------------------------------------------------------------- */
/* Arbeidskrav                                                            */
/*                                                                        */
/* Studentens kort svarer på «hva skal jeg levere, når» — fristen har     */
/* derfor mer vekt enn statusen, helt til noe er underkjent. Da er        */
/* tilbakemeldingen det viktigste på kortet.                              */
/* --------------------------------------------------------------------- */
.frist-naer { color: #7a5200; font-weight: 600; }
.frist-over { color: var(--rod); font-weight: 600; }

/* Tilbakemeldingen står i statuscella, rett under merket: en underkjenning
   uten begrunnelse er ubrukelig for den som skal rette den opp. Streken til
   venstre skiller den fra statusteksten uten å ta en egen kolonne. */
.ak-tilbakemelding-celle {
  margin-top: 0.3rem; padding-left: 0.5rem; font-size: 0.82rem;
  border-left: 3px solid var(--rod); color: var(--tekst-svak);
}
/* Vurderingskøen bruker det vanlige statusmerket — samme fylte merke, samme
   tre farger, samme komponent som ellers i appen. Det eneste som er særegent
   her er BREDDEN: en kolonne der merket skifter bredde fra rad til rad leses
   som støy. Regelen står på cellen, ikke på merket, så komponenten er urørt. */
.kol-vurdering .merke {
  min-width: 8.5rem;
  text-align: center;
}

/* Samme grunn: «Vurder» og «Endre vurdering» skal ikke gi to knappebredder. */
.knapp-vurder { min-width: 9.5rem; }

/* Og i vurderingskolonnen: «3 venter» og «Vurder» står under hverandre i samme
   kolonne, og skal ikke bytte bredde fra rad til rad. */
.kol-vurderingsknapp .knapp { min-width: 7.5rem; }

/* «Knyttet til»-cellen: merkene flyter, koble-knappen står til slutt. */
.ak-koblingcelle { display: flex; align-items: flex-start; gap: 0.3rem; min-width: 0; }
.ak-koblingcelle > :first-child { flex: 1 1 auto; min-width: 0; }
.ak-koblingcelle > .ikon-knapp { flex: 0 0 auto; }
/* Dokumentmerket er en handling (last ned / åpne), ikke bare en etikett. */
a.kobling-merke { text-decoration: none; }
a.kobling-merke:hover { background: var(--flate); text-decoration: underline; }
/* Merkene bærer full tittel i `title`. Cellen er smal, så teksten kappes med
   ellipse framfor å presse raden i høyden — pensumtitlene er lange. */
.ak-koblingcelle .kobling-merke {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Flere forsøk i én celle — nyeste øverst, uten at raden bygger høyde. */
.ak-celleliste { display: flex; flex-direction: column; gap: 0.15rem; }
.ak-celleliste > div {
  display: flex; gap: 0.4rem; align-items: baseline; min-width: 0;
}
/* min-width: 0 er ikke pynt. Et fleks-element krymper ikke under innholdets
   egen bredde uten den, og da slår text-overflow aldri inn — lenka vokser ut
   av cella i stedet for å bli kappet. Reglene sto her fra før og gjorde
   ingenting. */
/* `max-width` MAA staa her, ikke bare `min-width: 0`. Tabellen i
   vurderingsvinduet bygges for haand UTEN `table-layout: fixed` og uten
   kolonnebredder, saa cella vokser med innholdet: `flex: 0 1 auto` faar aldri
   noe aa krympe MOT, og ellipsen slo derfor aldri inn. Et filnavn som
   «Refleksjonsnotat etter samling 2 - Vigdis Dalseng - endelig versjon.pdf»
   dyttet tabellen forbi modalens 880px, og «Vurder»-knappen i siste kolonne
   havnet utenfor skjermen.
   16rem rommer ~30 tegn — nok til aa kjenne igjen fila. Hele navnet ligger i
   `title`. */
.ak-celleliste a {
  min-width: 0; flex: 0 1 auto; max-width: 16rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 780px) { .ak-celleliste a { max-width: 11rem; } }
.ak-forsok-tall {
  flex: 0 0 auto; font-family: var(--font-overskrift); font-weight: 700;
  color: var(--tekst-svak); font-size: 0.85rem;
}

/* Forvaltningens fordeling: en stolpe sier mer enn tre tall alene, men tallene
   står under — en stolpe uten tall kan ikke leses av. */
.ak-fordeling { min-width: 9rem; }
.ak-stolpe {
  display: flex; height: 0.5rem; background: var(--kant);
  border-radius: var(--radius); overflow: hidden;
}
.ak-stolpe-godkjent { background: var(--gronn); }
.ak-stolpe-levert { background: var(--gul); }
.ak-stolpe-avvist { background: var(--rod); }
.ak-fordeling-tall {
  margin-top: 0.2rem; font-size: 0.82rem; color: var(--tekst-svak);
}
/* Studentens egen oversikt: samme stolpe, men den staar alene over lista og
   ikke i en tabellcelle - da taaler den aa vaere litt tydeligere. */
.ak-egen-fordeling { min-width: 0; margin-bottom: 1rem; }
.ak-egen-fordeling .ak-stolpe { height: 0.7rem; }
.ak-egen-fordeling .ak-fordeling-tall {
  margin-top: 0.35rem; font-size: 0.88rem; color: var(--tekst);
}

/* --------------------------------------------------------------------- */
/* Vedlegg på en leksjon                                                  */
/*                                                                        */
/* Tittelen er en lenke og skal være det tydeligste på raden — filen skal */
/* kunne hentes med ett klikk. Filnavn, kategori og dato er kontekst.     */
/* --------------------------------------------------------------------- */
.dok-liste { list-style: none; margin: 0; padding: 0; }
.dok-rad {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.45rem 0; border-bottom: 1px solid var(--kant);
}
.dok-rad:last-child { border-bottom: none; }
.dok-tekst { flex: 1 1 auto; min-width: 0; }
.dok-meta { font-size: 0.82rem; color: var(--tekst-svak); margin-top: 0.1rem; }

/* Leksjonskoden foran vedlegget i pensumlista: uten den vet man ikke HVILKEN
   leksjon arket hører til når to leksjoner deler samme pensum. */
.vedlegg-kode {
  font-family: var(--font-overskrift); font-weight: 700;
  color: var(--aksent-mork); margin-right: 0.3rem; flex: 0 0 auto;
}
/* Dokumentnavnet forkortes framfor å brytes. Samme grep som .pensum-merke:
   et vedleggsnavn på tre linjer gjorde raden dobbelt så høy, og hele navnet
   står uansett i tittelteksten ved peking. */
.vedlegg-merke { max-width: 11rem; }
.vedlegg-merke > span:last-child {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* --------------------------------------------------------------------- */
/* Læringsmål — rader, ikke én tekstblokk                                 */
/* --------------------------------------------------------------------- */
/* Kategorivalget skal ikke sluke bredden fra selve målet. */
.mal-tabell .kol-mal-kategori { width: 11rem; }
.mal-tabell .kol-mal-kategori select { width: 100%; }
/* Målet er den viktigste kolonnen og får resten av plassen. */
.mal-tabell th:nth-child(4), .mal-tabell td:nth-child(4) { width: 45%; }

.mal-kategori dt { font-weight: 700; color: var(--tekst); }
.mal-liste { margin: 0.2rem 0 0.6rem; padding-left: 1.2rem; }
.mal-liste li { margin-bottom: 0.2rem; }
/* Gruppeoverskriften inne i en kategori («Grunnleggende bruk av DJI Pilot 2»).
   Svakere enn kategorien over, tydeligere enn målene under. */


/* Flervalg i skjema: avhukinger i rutenett framfor én lang kolonne. */
.flervalg-rutenett {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: 0.3rem 1rem;
}
.flervalg-valg {
  display: flex; align-items: center; gap: 0.45rem;
  font-size: 0.9rem; cursor: pointer;
}
.skjema-lest .flervalg-valg { cursor: default; }

/* --------------------------------------------------------------------- */
/* «Mine leksjoner» — instruktørens egne HI-oppgaver                      */
/*                                                                        */
/* Lista er en huskeliste, ikke en katalog. Derfor er kortene tettere enn */
/* et vanlig .kort, og det som MANGLER har mer visuell vekt enn det som   */
/* er på plass — det er manglene man åpner sida for å finne.              */
/* --------------------------------------------------------------------- */
/* Fire ruter, ikke tre: rollene fikk hver sin. 58rem er bredden som holder
   dem på én linje på en vanlig skjerm — på 44rem falt «Mangler noe» ned på en
   egen rad, og et nøkkeltall alene under de andre leses som noe annet enn
   nøkkeltall. */
.mine-ruter {
  max-width: 58rem;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
}
/* Nøkkeltallet som betyr «her er det noe å gjøre». Fargen er den samme
   gule som brukes til utkast og advarsler ellers i appen. */
.tf-rute-varsel { border-left: 3px solid var(--gul); }
.tf-rute-varsel .tf-rute-verdi { color: #7a5200; }

/* Gruppeoverskrift. Bolkene er tidsbaserte, og skal kunne skummes vertikalt —
   derfor en tynn strek framfor et nytt kort rundt hver bolk. */
.mine-gruppe {
  display: flex; align-items: baseline; gap: 0.5rem;
  margin: 1.4rem 0 0.6rem; padding-bottom: 0.25rem;
  font-size: 1rem; border-bottom: 1px solid var(--kant-mork);
}
.mine-gruppe-tall {
  font-family: var(--font); font-size: 0.82rem; font-weight: 400;
  color: var(--tekst-svak);
}

.mine-kort { margin-bottom: 0.7rem; padding: 0.8rem 1rem; }
/* Skal holdes snart OG mangler noe. Streken øverst skifter farge framfor at
   kortet får bakgrunn: en rad gule kort ville druknet hverandre. */
.mine-kort-haster { border-top-color: var(--gul); }

.mine-hode {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 0.6rem; flex-wrap: wrap;
}
.mine-tittel {
  flex: 1 1 18rem; min-width: 0;
  font-weight: 600; font-size: 1.0rem;
  display: flex; align-items: baseline; gap: 0.5rem;
}
.mine-kode {
  flex: 0 0 auto;
  font-family: var(--font-overskrift); font-size: 1.05rem; font-weight: 700;
  color: var(--aksent-mork); letter-spacing: 0.02em;
}
.mine-naar { flex: 0 0 auto; font-size: 0.88rem; color: var(--tekst-svak); }
.mine-naar-snart { color: #7a5200; font-weight: 600; }

.mine-detalj { margin-top: 0.2rem; font-size: 0.85rem; color: var(--tekst-svak); }

/* Rollemerket. To roller, to helt ulike beskjeder — «dette er ditt ansvar»
   og «du skal delta» — og de MÅ kunne skilles på et halvt sekund. Derfor
   fylt aksentfarge for HI og en rolig ramme for hjelperollen: det er ikke to
   varselnivåer, det er eierskap mot deltakelse. */
.mine-roller {
  display: flex; flex-wrap: wrap; gap: 0.35rem; margin-top: 0.35rem;
}
.mine-rolle {
  display: inline-block; flex: 0 0 auto;
  font-size: 0.72rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
  padding: 0.12rem 0.45rem;
  border: 1px solid transparent;
  cursor: help;
}
.mine-rolle-hi { background: var(--aksent); color: #fff; }
.mine-rolle-hjelp {
  background: var(--flate); color: var(--tekst-svak);
  border-color: var(--kant-mork);
}
/* Kilden står UTENFOR merket og uten versaler: den forklarer hvorfor
   leksjonen er i lista, og skal ikke konkurrere med rollen om oppmerksomhet. */
.mine-rolle-post {
  display: inline-flex; align-items: baseline; gap: 0.35rem; flex: 0 0 auto;
}
.mine-rolle-kilde { font-size: 0.78rem; color: var(--tekst-svak); }

/* Hvem ellers som er satt opp. Står mellom detaljene og manglene fordi det er
   det en hjelpeinstruktør leter etter: hvem avklarer jeg med? */
.mine-hvem {
  margin-top: 0.3rem; font-size: 0.85rem;
  display: flex; flex-wrap: wrap; gap: 0.35rem;
}
.mine-hvem-hode { color: var(--tekst-svak); }

/* Kortet for en hjelperolle er dempet i kanten. Ingen bakgrunnsfarge: en liste
   der annenhver rad er tonet ned blir stripete og vanskeligere å skumme enn
   den var. */
.mine-kort-hjelp { border-left: 3px solid var(--kant-mork); }

/* Filteret står over lista, ikke inni den. */
.mine-filter { margin: 1rem 0 0; }

.mine-mangler {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.35rem; margin-top: 0.55rem;
}
.mine-mangler-hode {
  font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em;
  font-weight: 600; color: #7a5200; margin-right: 0.15rem;
}
.mine-mangel { background: #fff5e0; border-color: var(--gul); color: #7a5200; }
/* Manglene på en ANNENS leksjonsplan. Samme opplysning, men ikke din oppgave —
   den gule advarselsfargen ville sagt at du skulle gjøre noe med den. */
.mine-mangler-annen .mine-mangler-hode { color: var(--tekst-svak); }
.mine-mangler-annen .mine-mangel {
  background: var(--flate); border-color: var(--kant-mork);
  color: var(--tekst-svak);
}
.mine-klar { margin-top: 0.55rem; font-size: 0.88rem; color: var(--gronn); }

/* Tellingene er kontekst, ikke krav — minst vekt på sida. */
.mine-tall {
  display: flex; flex-wrap: wrap; gap: 0.25rem 0.9rem;
  margin-top: 0.45rem; font-size: 0.82rem; color: var(--tekst-svak);
}
.mine-tall span + span::before { content: '· '; }

.mine-handlinger {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 0.5rem; margin-top: 0.7rem;
}

/* --------------------------------------------------------------------- */
/* Kassasjonsplan                                                        */
/*                                                                       */
/* Merknaden om at ingenting slettes automatisk står FØRST og med vekt.  */
/* En liste over «hva som har passert fristen» leses lett som en          */
/* slettejobb som allerede har kjørt.                                    */
/* --------------------------------------------------------------------- */
.bevaring-merknad {
  margin: 0 0 0.8rem; padding: 0.6rem 0.8rem; font-size: 0.9rem;
  background: var(--flate); border: 1px solid var(--kant);
  border-left: 4px solid var(--gul);
}
.bevaring-forfalt { color: #7a5200; font-weight: 600; cursor: help; }

/* --------------------------------------------------------------------- */
/* Studieplanen som fil, øverst på Studieplan-sida                        */
/*                                                                       */
/* Dokumentet er det studenten faktisk skal lese — matrisen under er      */
/* forvaltningens verktøy. Det står derfor først, og med nok vekt til at  */
/* det ikke leses som en av merkeboblene lenger ned.                     */
/* --------------------------------------------------------------------- */
.studieplan-fil {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-wrap: wrap;
  padding: 0.85rem 1rem;
  margin: 0 0 1rem;
  background: var(--flate);
  border: 1px solid var(--kant);
  border-top: 4px solid var(--aksent);
}
/* Ikonet er en inline-SVG, ikke emoji: et fargeemoji kan ikke ta farge fra
   `color`, og skulle her matche streken over. `currentColor` gjør at de to
   ikke kan komme i utakt om aksenten endres. */
.studieplan-fil-ikon {
  flex: 0 0 auto;
  color: var(--aksent);
  display: inline-flex;
  align-items: center;
}
.studieplan-fil-ikon svg { display: block; }
.studieplan-fil-tekst { flex: 1 1 18rem; min-width: 0; }
.studieplan-fil-tittel { font-weight: 700; font-size: 0.95rem; }
.studieplan-fil-meta { font-size: 0.85rem; color: var(--tekst-svak); }
.studieplan-fil-knapper { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-left: auto; }
/* Pensumetiketten inne i et merke: understreking sier at den kan åpnes, mens
   fargen arves fra merket den står i — et blått lenkenavn inne i et lilla
   pensummerke leses som to ting. */
.pensum-etikett { color: inherit; text-decoration: underline; cursor: pointer; }

/* Nullstilling i vurderingsvinduet. Skilt fra skjemaet med en strek fordi den
   ikke er et vurderingsvalg: de andre handlingene kan gjøres om, denne sletter
   studentens fil for godt. */
.nullstill-felt {
  margin-top: 1.25rem; padding-top: 1rem;
  border-top: 1px solid var(--kant, #d9dde3);
}
.nullstill-felt .hjelpetekst { margin-bottom: 0.6rem; }

.pensum-merke {
  /* Smalt nok til at to merker får plass ved siden av hverandre i kolonnen —
     ellers blir hver leksjon med flere pensumposter fem linjer høy. */
  max-width: 8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
}

/* Koblinger som finnes, men som ikke er i bruk i den valgte puljen. De teller
   ikke som dekning her — men de skal SES, ellers ser en eksisterende kobling
   ut som om den ikke finnes. */
.kobling-merke-passiv { opacity: 0.55; border-style: dashed; }
.merke-fotnote { font-size: 0.72rem; opacity: 0.8; }

/* --------------------------------------------------------------------------
   Dra og slipp i ukeskalenderen

   Kantsonene (7 px topp/bunn) endrer start- eller sluttid; midten flytter hele
   økta. Markørene vises bare på hover, slik at kalenderen ellers ser ut som før.
   -------------------------------------------------------------------------- */
.kal-blokk-drabar { touch-action: none; }
.kal-blokk-drabar::before,
.kal-blokk-drabar::after {
  content: ''; position: absolute; left: 0; right: 0; height: 7px;
  opacity: 0; transition: opacity .12s;
}
.kal-blokk-drabar::before { top: 0; }
.kal-blokk-drabar::after { bottom: 0; }
.kal-blokk-drabar:hover::before,
.kal-blokk-drabar:hover::after {
  opacity: 1;
  background: linear-gradient(var(--aksent), var(--aksent)) center/1.6rem 2px no-repeat;
}
.kal-blokk-drar {
  opacity: 0.85;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.28);
  z-index: 20;
  cursor: grabbing !important;
}
/* Flytting: originalen blir stående dempet der den var, og en flytende kopi
   følger pekeren og snapper til dag og tidspunkt. Kopien tar ingen
   pekerhendelser — treff-testen skal se kolonnen under den. */
.kal-blokk-kilde {
  opacity: 0.4;
  outline: 1px dashed var(--aksent);
  outline-offset: -1px;
}
.kal-blokk-spokelse {
  opacity: 1;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
  z-index: 20;
  pointer-events: none;
}

/* Selvbetjent innsyn på dashbordet — rolig, men ikke gjemt. */
.egne-opplysninger {
  display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap;
  border: 1px solid var(--kant); border-left: 3px solid var(--aksent);
  background: var(--flate); padding: 0.6rem 0.85rem; margin-bottom: 1.25rem;
  font-size: 0.9rem;
}


/* --------------------------------------------------------------------- */
/* Telefon                                                               */
/*                                                                       */
/* ALT som gjelder små skjermer står i denne ene blokka. Skrivebordet er  */
/* urørt — det er en forutsetning: appen brukes til daglig på PC, og en   */
/* forbedring for telefonen skal ikke kunne flytte noe der.              */
/*                                                                       */
/* Den gamle regelen krympet sidefeltet til 60 px og satte menyteksten   */
/* til `font-size: 0`. Igjen sto en kolonne med tall — 01, 04, 06 — uten */
/* ord og uten ikoner. Menyen var der, men bare for den som husket hva    */
/* tallene betydde.                                                      */
/* --------------------------------------------------------------------- */
/* Mellombaandet: PC-oppsettet har et gulv paa ca. 1016px - sidefelt 220 +
   etikettene + min-width 180 paa studievelgeren + 220 paa puljevelgeren +
   hoyresida. Med reelle studienavn ble det maalt til 1160px. I hele baandet
   781-1160 rullet derfor HELE siden vannrett: paa 781px maalte
   document.scrollWidth 1160, og «Logg ut» laa 318px utenfor skjermkanten.
   En telefon i LIGGENDE modus (932px) treffer nettopp dette baandet, og faar
   verken telefonoppsettet eller et PC-oppsett som faar plass.

   Gulvet senkes i stedet for at bruddpunktet flyttes: da beholder nettbrett
   og smaa skjermer PC-oppsettet, men det krymper framfor aa flyte over. */
@media (max-width: 1160px) and (min-width: 781px) {
  .toppfelt { padding-inline: 0.75rem; }
  .studie-etikett, .pulje-etikett, .topp-dato { display: none; }
  /* Samme grunn som paa telefon: merket har white-space: nowrap og tar 66px
     som puljenavnet trenger bedre. Statusen staar uansett paa puljesida. */
  #pulje-status-merke { display: none; }
  .identitet-merke { max-width: 9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  #studie-velger, .studie-velger { min-width: 0; flex: 1 1 8rem; }
  .pulje-velger { min-width: 0; flex: 1 1 10rem; }
  .toppfelt-venstre { flex: 1 1 auto; min-width: 0; }
  .toppfelt-hoyre { flex: 0 1 auto; min-width: 0; }
}

@media (max-width: 780px) {
  /* Blokka står SIST i fila med vilje. Den er en overstyring av alt over, og
     ligger den midt inne, vinner en senere grunnregel over den uten at noe sier
     fra — «.sidefelt-logo { flex-direction: column }» 500 linjer lenger nede
     gjorde logolinja 71 px høy i stedet for 50, og feilen var usynlig i koden.
     Legger du til noe her, hold det her nede. */

  /* Sidefeltet legger seg øverst, med menyen bak en hamburger, og BLIR
     STÅENDE når man ruller. Logoen og hamburgeren er det eneste som alltid
     må være innen rekkevidde: uten dem måtte man rulle helt til topps for å
     bytte side. Toppfeltet under (puljevelger, «Logg ut») får rulle bort —
     to faste linjer ville spist en fjerdedel av skjermen. */
  .layout { flex-direction: column; }
  .sidefelt {
    width: 100%;
    height: auto;
    position: sticky;
    top: 0;
    z-index: 30;
    flex-direction: column;
  }
  .toppfelt { position: static; }
  /* MERK: tabelloverskriftene er `position: sticky`, men de klistrer seg til
     .tabell-wrap — et rullefelt klipper sitt eget sticky-innhold — og den
     ruller bare vannrett. De følger altså IKKE med loddrett, hverken her
     eller på PC-en. Et `top`-gulv her ville sett ut som en løsning og ikke
     gjort noe; skal overskriftene bli stående, må rullingen flyttes. */
  /* Logorubrikken deler høyde med toppfeltet på PC-en (--topplinje). På
     telefonen er skjermhøyden knapphetsgodet, og de står ikke lenger side ved
     side — da er det ingen strek som skal flukte. */
  .sidefelt-logo {
    min-height: 0;
    padding: 0.2rem 0.75rem;
    gap: 0.4rem;
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
  }
  .logo-tittel { font-size: 0.9rem; white-space: nowrap; }
  /* «PHS · Dronetjenesten» brakk logolinja i to og kostet 46 px av høyden.
     Den sier ikke noe man trenger på hver eneste skjerm. */
  .logo-undertittel { display: none; }

  /* Menyen ligger BAK en hamburger. Den vannrette stripa som sto her først
     løste lesbarheten, men ikke rullingen: seksten punkter i én rad betyr at
     halvparten alltid er utenfor skjermen, og man drar fram og tilbake for å
     finne dem. Lukket meny koster null piksler. */
  .meny-knapp {
    display: block;
    background: transparent;
    border: 0;
    color: inherit;
    font-size: 1.5rem;
    line-height: 1;
    padding: 0 0.5rem 0 0;
    min-width: 44px;
    min-height: 44px;
    cursor: pointer;
  }
  .nav-rullefelt { display: none; flex: 0 0 auto !important; }
  .sidefelt.meny-apen .nav-rullefelt {
    display: block;
    /* 60vh ga 486px synlig av 984px innhold - noeyaktig halve menyen laa i et
       indre rullefelt uten noe som antydet at det fantes mer. Hele den ledige
       hoyden er riktigere: menyen er et overlegg og lukkes ved valg. */
    max-height: calc(100dvh - 3.2rem);
    /* Siste punkt fades ut, saa det syns at lista fortsetter. */
    mask-image: linear-gradient(#000 calc(100% - 1.5rem), transparent);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border-top: 1px solid rgba(255, 255, 255, 0.12);
  }
  /* Åpen meny er den vanlige loddrette lista — den er lettest å lese, og nå
     koster den ingenting når den er lukket. Gruppetitlene blir stående: de er
     det som gjør seksten punkter til seks bolker. */
  .nav-seksjon { margin: 0; }
  .nav-gruppe-tittel { padding-top: 0.6rem; }
  .nav-lenke {
    display: flex;
    align-items: center;
    white-space: nowrap;
    padding: 0 0.9rem;
    min-height: 44px;                     /* fingerstørrelse */
    border-left: 0;
    border-bottom: 3px solid transparent;
  }
  .nav-lenke.aktiv { border-left: 0; border-bottom-color: #fff; }
  /* Nummeret er en PC-snarvei. Selektoren må slå den i .nav-lenke-konteksten,
     ellers blir `inline-block` bare blokkifisert av flex-forelderen. */
  .nav-lenke .nav-nr { display: none; }
  .sidefelt-bunn { display: none; }

  /* Toppfeltet fikk ikke plass til dato + «Logg ut» og dyttet HELE siden
     sidelengs. Datoen er den minst nødvendige av de to. */
  .toppfelt {
    min-height: 0;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
  }
  .topp-dato { display: none; }
  /* Etiketten «Aktiv pulje» tar en hel linje. Nedtrekket sier selv hvilken
     pulje som er valgt, så ordene er det som må vike — ikke selve valget. */
  .pulje-etikett { display: none; }
  /* Venstre- og hoyrebolken kjempet om én linje. .toppfelt hadde
     flex-wrap: wrap, men .toppfelt-venstre sto paa flex-basis 0 og overfylte
     derfor ALDRI - innpakkingen ble aldri utloest. Hoyresida sto samtidig paa
     flex: 0 0 auto og krympet ikke. Maalt: studievelgeren 17px, puljevelgeren
     49px. Naa faar bolkene hver sin linje. */
  .toppfelt { row-gap: 0.5rem; }
  .toppfelt-hoyre { order: 1; flex: 1 1 100%; justify-content: flex-end; }
  .toppfelt-venstre { order: 2; flex: 1 1 100%; min-width: 0; gap: 0.4rem; }
  .studie-bolk { flex: 1 1 9rem; min-width: 0; }
  .pulje-velger { flex: 1 1 11rem; min-width: 0; width: auto; }
  /* Statusmerket er sekundaert, puljenavnet er informasjonen - og merket har
     white-space: nowrap og spiste 72 av 150px. */
  #pulje-status-merke { display: none; }
  .pulje-velger { min-width: 0; width: 100%; }
  /* To nedtrekk på én smal linje: studiet får mindre plass enn kullet. Kullet
     er det man bytter oftest, og studienavnet er som regel gjenkjennelig på
     de første tegnene. */
  .studie-bolk { flex: 1 1 40%; min-width: 0; }
  #studie-velger { min-width: 0; width: 100%; }
  .toppfelt-hoyre { flex: 0 0 auto; gap: 0.5rem; }
  .identitet-merke { max-width: 8rem; overflow: hidden; text-overflow: ellipsis; }

  .skjema { grid-template-columns: 1fr; }
  .innhold { padding: 1rem; }

  /* Timeføringspanelet lå UTENFOR skjermen på telefon.
     Instruktørtabellen ruller vannrett i `.tabell-wrap`, og det utfoldede
     panelet ligger i en `<td colspan>` — altså like bredt som TABELLEN, ikke
     som skjermen. `.tf-strekk` skjøv slettknappen til høyre kant av de 556px
     tabellen krever, og målt ved 375px sto den 152px forbi skjermkanten. Raden
     var slettbar hele tiden; knappen var bare umulig å få øye på uten å rulle
     en tabell sidelengs inni et utfoldet panel.

     `position: sticky; left: 0` fester panelet til venstre kant av rullefeltet,
     så det blir stående uansett hvor tabellen er rullet. Bredden må settes
     eksplisitt — ellers arver panelet tabellens bredde igjen, og da bryter
     ikke `.tf-linje-nar` slik den skal.

     100vw - 2rem er `.innhold` sin padding, - 2rem er `.instr-eksp > td` sin,
     - 2px er tabellrammen. Samme regnestykke som `.tl-rute` bruker.

     MERK at dette er VANNRETT sticky i et vannrett rullefelt. Kommentaren
     lenger oppe om at `.tabell-wrap` klipper sitt eget sticky-innhold gjelder
     `top` i loddrett retning, og er en annen sak. */
     Selektoren er bundet til `td >` med vilje: i KORTMODUS ligger panelet
     inne i kortet, som alt har skjermbredde, og da ville denne bredden og
     stickyen vært feil. Regelen gjelder bare tabellvarianten — og den står
     igjen som vern for visninger som ikke har mobilkort. */
  td > .instr-eksp-innhold {
    position: sticky; left: 0;
    width: calc(100vw - 4rem - 2px);
    max-width: calc(100vw - 4rem - 2px);
  }

  /* MERK: studieløpstidslinjen (.tl-*) står med vilje UENDRET her. Datoen ble
     en periode flyttet ned under tittelen og forkortet til «1/3»; brukeren
     ville ha den tilbake på én linje i full form, som på PC. Tittelen klippes
     da med ellipse i en 150 px etikettkolonne — det er en bevisst avveining,
     ikke noe som er glemt.

     `.dato-lang`/`.dato-kort` under gjelder DASHBORDETS tidslinje, som viser
     bare startdato på bjelkene her. Den er en annen komponent. */
  .dato-lang { display: none; }
  .dato-kort { display: inline; }

  /* Søkefeltet er viktigere på telefon enn noe annet sted: der er lista det
     eneste på skjermen, og rulling koster mest. Det får hele bredden. */
  .tabell-sok { flex: 1 1 auto; }

  /* Tabellene er 780–930 px brede og rulles sidelengs i sitt eget felt.
     Uten en fast førstekolonne mister man raden av syne før man er halvveis
     ut i den — man ser et tall uten å vite hvem eller hva det gjelder. */
  .tabell-wrap { -webkit-overflow-scrolling: touch; }
  .tabell { font-size: 0.85rem; }
  .tabell th, .tabell td { padding: 0.5rem; }
  .tabell thead th:first-child,
  .tabell tbody td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--flate);
    box-shadow: 1px 0 0 var(--kant);
  }
  .tabell thead th:first-child { z-index: 2; background: #e7e7ea; }
  .tabell tbody tr:hover td:first-child { background: #f0f0f1; }

  /* Fingerstørrelse på alt som skal trykkes. */
  .knapp { min-height: 44px; }
  .ikon-knapp { min-width: 40px; min-height: 40px; padding: 0.4rem; }
  .rad-handlinger { gap: 0.25rem; }

  /* Radhandlingene bak én ⋯. Kolonnen går fra 143 px til 40 i studentlista —
     den var den bredeste av alle, bredere enn navnet. */
  .rad-meny-knapp { font-size: 1.2rem; letter-spacing: 0.05em; }
  .kol-handling { width: 44px; }
  /* Inne i dialogen skal knappene være en LISTE, ikke tre ikoner på rad: der
     er det plass til å treffe dem, og til å se hva de gjør. */
  .rad-meny-valg { display: flex; flex-direction: column; gap: 0.35rem; }
  .rad-meny-valg .rad-handlinger { flex-direction: column; align-items: stretch; gap: 0.35rem; }
  .rad-meny-valg .ikon-knapp,
  .rad-meny-valg .knapp {
    width: 100%;
    min-height: 44px;
    justify-content: flex-start;
    text-align: left;
    border: 1px solid var(--kant-mork);
    background: var(--flate);
  }

  /* Tallkortene stakk 15 px ut av skjermen: `min-width: 150px` pluss
     mellomrom er mer enn 375 px deler på to. To i bredden er fortsatt
     riktig — fire kort under hverandre blir en lang rulling. */
  .tall-boks { min-width: 0; flex: 1 1 calc(50% - 0.5rem); padding: 0.75rem 0.8rem; }
  .tall-rad { gap: 0.6rem; }
  .gruppe-liste { grid-template-columns: 1fr; }

  /* ---- Trykkflater ------------------------------------------------------
     Alle tallene under er MAALT paa 375px foer og etter, ikke anslaatt.
     44px er gulvet et fingertrykk trenger; blokka satte det allerede for
     .knapp og .nav-lenke, men hoppet over alt annet man faktisk trykker paa. */

  /* Lukkeknappen i modaler var 20.6 x 22.5 px - mindre enn halve gulvet, og
     den er den eneste veien ut av en dialog paa telefon. */
  .modal-lukk {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0;
  }

  /* Nedtrekkene i toppfeltet og verktoeylinjene. Nedtrekk INNE i tabellrader
     staar med vilje utenfor - de faar sin egen regel under. */
  .pulje-velger, .filter-velger, .rapport-velger, .status-select,
  .studie-velger, #studie-velger { min-height: 44px; }

  /* «Min profil» var 119 x 22 px, og er den ENESTE veien inn til egne
     opplysninger - det finnes ikke noe menypunkt for den. */
  .identitet-merke {
    min-height: 44px; max-width: 8rem;
    display: inline-flex; align-items: center;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* Inline-redigering i tabellene var 26px hoy. Radene blir hoeyere av dette,
     og det er prisen: et felt man ikke treffer er ikke redigerbart i det hele
     tatt. Avkryssingen var 16 x 16 px i en 45px kolonne - 13 % av flaten. */
  .tabell .inline-input, .tabell .celle-input { min-height: 40px; }
  .inline-checkbox, .tabell input[type="checkbox"] {
    width: 24px; height: 24px;
  }
  .kol-sel-tilbud, .tabell td:has(> input[type="checkbox"]) { padding: 0.3rem; }

  /* Sorteringen skjer ved aa trykke paa kolonneoverskriften, og de var 25px. */
  .tabell thead th.sorterbar { padding-block: 0.85rem; }

  /* ---- Verktoeylinja og filtrene ----------------------------------------
     Maalt paa 375px FOER: siden var 485px bred - 110px overflyt - og
     «Rangér distrikt» sluttet presis paa 485. Tre ting sammen:

       .filtre hadde `margin-left: auto`   -> skjoev bolken mot hoyre
       .filtre hadde flex-wrap: nowrap     -> to velgere + en nowrap-knapp
                                              MAATTE staa paa én linje
       .filter-velger maaler seg etter sitt lengste alternativ
                                           -> «Moere og Romsdal
                                              politidistrikt» ga 211px

     Ingen av dem hadde mobiloverstyring. Dette gjelder ALLE visninger med
     verktoeylinje, ikke bare seleksjon. */
  .verktoy-linje { width: 100%; }
  .verktoy-linje > .knapp { flex: 1 1 100%; }
  .verktoy-linje .filtre {
    margin-left: 0;
    flex-wrap: wrap;
    width: 100%;
    gap: 0.5rem;
  }
  /* Velgerne deler linja og faar krympe. Uten min-width: 0 staar flex-barnet
     paa `min-width: auto`, altsaa innholdets bredde, og gir seg ikke. */
  .filter-felt { flex: 1 1 9rem; min-width: 0; }
  .filter-felt select, .filtre select { width: 100%; min-width: 0; }
  /* Knappen tar sin egen linje. align-self: flex-end ga en loes knapp som
     hang i hoyre kant av en linje den likevel ikke fikk plass paa. */
  .sel-ranger-knapp { align-self: stretch; flex: 1 1 100%; }

  /* ---- Navn og «Logg ut» i den moerke logolinja ------------------------
     Flyttet dit av app.js (plasserIdentitet). Grunnen er ikke plass alene:
     logolinja staar STICKY, mens toppfeltet under ruller bort. Laa de i
     toppfeltet, matte man rulle helt til topps for aa logge ut.

     De to knappene er bygget for LYS bunn - .identitet-merke og
     .knapp-sekundar bruker begge var(--flate) og var(--aksent). Paa
     #1d2d3d blir det lys tekst paa lys flate. Derfor egne farger her. */
  .sidefelt-logo .toppfelt-hoyre { margin-left: auto; flex: 0 0 auto; }
  .toppfelt-hoyre-moerk { display: flex; align-items: center; gap: 0.4rem; }

  /* Lavere enn 44px-gulvet, med vilje. Utdanningsleder ba om det, og de to
     staar i en STICKY linje - hver piksel her koster skjermhoyde paa hver
     eneste side. 34px er fortsatt et komfortabelt tommeltreff for en knapp
     som ikke er en primaerhandling, og med etternavn alene er pilla kort. */
  .toppfelt-hoyre-moerk .identitet-merke {
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: #eaf0f7;
    max-width: 7rem;
    min-height: 34px;
    padding: 0 0.5rem;
    font-size: 0.82rem;
  }
  .toppfelt-hoyre-moerk .knapp-sekundar {
    background: transparent;
    border-color: rgba(255, 255, 255, 0.32);
    color: #eaf0f7;
    min-height: 34px;
    padding: 0 0.55rem;
    font-size: 0.82rem;
  }
  .toppfelt-hoyre-moerk .knapp-sekundar:hover { background: rgba(255, 255, 255, 0.10); }

  /* Logotittelen maa gi fra seg plassen. Undertittelen er allerede skjult
     paa telefon; tittelen kappes framfor aa presse de to knappene ut. */
  .sidefelt-logo .logo-tittel {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }

  /* ---- Modaler og leksjonskortet ---------------------------------------
     En modal paa telefon skal fylle skjermen. Som flytende dialog fikk den
     3rem luft i toppen, 1rem i sidene og en `max-height` paa 100vh - 6rem:
     kortet ble 89 % av skjermen med en halvsynlig bakgrunn rundt, og
     lesefeltet krympet til 577 av 812 px. Det er ikke en dialog man kan lese
     en hel leksjonsplan i.

     Hodet og foten staar stille, kroppen ruller. */
  .modal-overlay { padding: 0; align-items: stretch; overflow: hidden; }
  /* `!important` paa max-width: enkelte dialoger setter sin egen bredde
     inline (`modal({ bredde: '560px' })`), og en inline-stil slaar et vanlig
     regelsett. Den skal ikke gjelde paa en 375 px skjerm. */
  .modal {
    max-width: 100% !important; width: 100%;
    max-height: none; height: 100%;
    border-radius: 0; box-shadow: none;
  }
  .modal-kropp { flex: 1 1 auto; min-height: 0; padding: 1rem; }
  .modal-hode { padding: 0.75rem 1rem; }
  /* Krysset var ~24px hoyt. Det er lukkeknappen for hele visningen. */
  .modal-lukk {
    min-width: 44px; min-height: 44px;
    display: flex; align-items: center; justify-content: center;
    margin: -0.5rem -0.5rem -0.5rem 0;
  }
  .modal-footer { padding: 0.7rem 1rem; }

  /* SEKSJONSOVERSKRIFTENE var 22,5px - `.seksjon-tittel` er en `h2` uten egen
     `font-size`, saa den arvet nettleserens 1.5em. Like stor som sidetittelen,
     og i et kort med etiketter paa 10,8px ble spennet fra minste til stoerste
     tekst mer enn dobbelt. */
  .modal .seksjon-tittel { font-size: var(--t-tittel); margin-bottom: 0.4rem; }

  /* Faktaboksen: to kolonner framfor fri flyt. Med `gap: 0 2rem` og
     `flex-wrap` la postene seg ujevnt - to paa foerste linje, en paa andre -
     og etikettene sto ikke under hverandre. */
  .leksjon-fakta {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.55rem 0.9rem; padding: 0.7rem 0.8rem;
  }
  .leksjon-fakta-etikett { font-size: var(--t-mikro); }
  .leksjon-fakta-verdi { font-size: var(--t-normal); }

  /* Tekststoerrelsene i kortet laa paa 22,5 / 15 / 14,3 / 13,5 / 12,8 / 10,8 -
     seks trinn, fire av dem utenfor typeskalaen. Naa: overskrift, broedtekst,
     etikett. Tre nivaaer med hver sin oppgave. */
  .modal .kobling-tekst,
  .modal .pensum-post-tittel { font-size: var(--t-normal); }
  .modal .pensum-post-apne { font-size: var(--t-brod); }
  .modal .leksjon-tekst, .modal .leksjon-def dd { font-size: var(--t-normal); }
  /* Loepende avsnitt arvet 1rem (15px) og sto stoerre enn tittelen i lista
     rett under. Alt som er broedtekst i kortet skal vaere ETT trinn. */
  .modal-kropp p, .modal .hjelpetekst, .modal .leksjon-bolk p { font-size: var(--t-normal); }
  /* Ett etikettnivaa, ikke to. `dt` laa paa 11,7px og faktaetiketten paa
     10,2px - to stoerrelser for samme rolle, med hver sin begrunnelse som
     ingen kan se forskjell paa i bruk. */
  .leksjon-fakta-etikett { font-size: var(--t-liten); }

  /* Pensumposten i kortet: tittelen tar linja, kildene staar til hoyre med
     full trykkflate. `align-items: baseline` gjorde ikonene skjeve. */
  /* Definisjonslista STABLES. `.leksjon-def` faar 1fr utenfor modaler paa
     telefon (linje 695), men `.modal .leksjon-def` satte to kolonner igjen med
     hoyere spesifisitet. Med 7-11rem til ledeteksten satt verdien igjen med
     ~180px og brakk i tre linjer der ledeteksten tok en. */
  .modal .leksjon-def { grid-template-columns: 1fr; gap: 0.1rem; }
  .modal .leksjon-def dt { margin-top: 0.7rem; }
  .modal .leksjon-def dt:first-child { margin-top: 0; }

  /* Pensumposten paa EN linje: tittelen tar plassen som blir til overs,
     kildene staar til hoyre. `flex: 1 1 20rem` ba om 300px av 343 og dyttet
     ikonene ned paa egen linje. */
  /* `nowrap`: posten skal vaere EN rad. Med `wrap` tok den lange tittelen
     hele bredden og dyttet ikonene ned paa en linje for seg — 99 px for en
     enkelt pensumpost. Tittelen brekker inni sin egen kolonne i stedet. */
  .modal .pensum-post {
    align-items: center; flex-wrap: nowrap; gap: 0.5rem; padding: 0.35rem 0.5rem;
  }
  .modal .pensum-post-tittel { flex: 1 1 auto; min-width: 0; }
  .modal .pensum-post-apne { flex: 0 0 auto; margin-left: 0; }
  .modal .pensum-post-apne { display: flex; align-items: center; gap: 0.15rem; margin-right: -0.35rem; }

  /* ---- Tidslinjene -----------------------------------------------------
     Begge er VANNRETTE av natur. De skal rulle i sin egen boks med et
     lesbart gulv - ikke klemmes sammen til ulesbarhet, og ikke dra siden.

     Studieloepets Gantt hadde en klistret etikettkolonne paa 150px av ca.
     303px tilgjengelige. Halve skjermen gikk til navnene, og selve tidslinja
     fikk 153px. Kolonnen ned til 92px gir 211px til det man faktisk kom for. */
  /* ETIKETTKOLONNEN VAR FOR SMAL TIL AA VISE NOE. 92px minus padding gir
     76px innhold, mens prikk (8) + to mellomrom (12) + datofeltet (88, og
     `flex: none`) alene krever 108. `.tl-tittel` ble presset til 0px og var
     helt usynlig, og datoen ble klippet midt i «17.11.-02.12.».

     Rettelsen er aa slutte aa presse HELE spennet inn i skjermbredden. Hver
     maaned faar en fast bredde, regnet slik at noyaktig fire av dem faar
     plass i rammen; de ovrige naas ved aa rulle sidelengs, som rammen alltid
     har kunnet. Da frigjoeres bredden til de tre maanedene man ikke lenger
     ser, og den gaar til etikettkolonnen - som dermed rommer bade dato og
     navn.

     100vw - 2rem er `.innhold` sin padding (1rem per side), - 2px er rammens
     border. */
  .tl-rute {
    --tl-etikett: 200px;
    --tl-synlige-mnd: 4;
    --tl-mnd-bredde: calc((100vw - 2rem - 2px - var(--tl-etikett)) / var(--tl-synlige-mnd));
    min-width: calc(var(--tl-etikett) + var(--tl-mnd-antall, 4) * var(--tl-mnd-bredde));
  }
  /* «OKT 25» er 43px i en maanedsrute paa ~36px og ble klippet til «OKT 2».
     Aarstallet staar uansett i statuslinja rett over. */
  .tl-mnd-aar { display: none; }

  /* Dashbordets tidslinje SKALERER - alt er plassert i prosent - saa den
     trenger ikke rulle.

     Foerste forsok ga den et gulv paa 460px og en rullebeholder; da matte man
     dra i den for aa se hele, og en tidslinje man ikke ser hele av er ikke en
     tidslinje. Andre forsok skjulte alle MELLOMETIKETTENE. Da sto den igjen
     som en rad prikker uten aa fortelle NAAR noe skjer - og det var nettopp
     det som ble savnet.

     Naa faar de plass, fordi de er korte: merket er «T1»/«S2»/«F1» (~14px) i
     en rekke OVER aksen, datoen «2/8» (~16px) i en rekke UNDER. Hver rekke
     konkurrerer bare med seg selv, og dashboard.js sprer det som fortsatt
     kolliderer sidelengs.

     Hoeydebudsjettet er regnet med 1rem = 15px (`html, body` paa linje 173):
       I DAG-merke   top 0   h ~13   ->  13
       merkerekka    top 16  h ~11   ->  27
       bjelke        top 31  h  12   ->  43   (akse paa 37)
       datorekka     top 47  h ~10   ->  57
     62px daekker det med luft; 78px var mer enn det trengte, og likevel for
     lite for en dato uten line-height. */
  .tidslinje { height: 62px; overflow: hidden; }
  .tidslinje-plot { left: 12px; right: 12px; }
  .tidslinje-akse { top: 37px; }
  .tidslinje-progresjon { top: 36px; }
  .tidslinje-punkt { top: 33px; width: 8px; height: 8px; }
  .tidslinje-bjelke { top: 31px; height: 12px; }
  .tidslinje-bjelke.liten { top: 33px; height: 8px; }
  .tidslinje-punkt.eksamen { top: 30px; width: 14px; height: 14px; }
  .tidslinje-idag { top: 14px; bottom: 14px; }
  .tidslinje-idag-merke { top: 0; font-size: 0.62rem; line-height: 1.15; padding: 1px 6px; }
  .tidslinje-etikett { top: 16px; font-size: 0.62rem; }
  .tidslinje-etikett-dato { top: 47px; font-size: 0.58rem; }
  /* EKSAMEN staar paa left:100%. Tegneflata er innrykket 12px, saa merket
     klippes ikke lenger - men hoeyrestillingen beholdes: den holder det unna
     naboen, som staar tettest nettopp her paa slutten. */
  .tidslinje-etikett.eksamen,
  .tidslinje-etikett-dato.eksamen { text-align: right; }
}

/* --------------------------------------------------------------------------- *
   Se appen som en annen bruker
   -------------------------------------------------------------------------- */
/* Banneret staar mellom toppfeltet og innholdet, over HELE bredden. Gult og
   ikke rodt: dette er en tilstand man har valgt selv, ikke en feil. Men det
   maa vaere umulig aa overse - en glemt veksling ser ellers ut som at appen
   plutselig mangler halve innholdet. */
.vekslingsbanner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  padding: 0.5rem 1.25rem;
  background: color-mix(in srgb, var(--gul) 18%, var(--flate));
  border-bottom: 2px solid var(--gul);
  font-size: var(--t-liten);
  color: var(--tekst);
}

/* `flex: 1 1 0` og ikke bare `min-width: 0`: uten den tar teksten sin fulle
   bredde, knappen faar ikke plass ved siden av og faller ned paa egen linje.
   Maalt paa 375px ble banneret 89px hoyt slik; med denne 60px. */
.vekslingsbanner-tekst { flex: 1 1 0; min-width: 0; }

.vekslingsbanner-lest {
  color: var(--tekst-svak);
}

.vekslingsbanner .knapp {
  flex: 0 0 auto;
  background: var(--aksent-mork);
  color: #fff;
  border-color: transparent;
}

/* Velgeren i «Min profil». */
.visningsveksler {
  margin: 1rem 0 0;
  padding: 0.85rem 1rem;
  background: var(--flate);
  border: 1px solid var(--kant);
  border-top: 3px solid var(--aksent);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.visningsveksler-tittel {
  font-family: 'Barlow Condensed', system-ui, sans-serif;
  font-weight: 600;
  font-size: var(--t-tittel);
  color: var(--aksent-mork);
  line-height: 1.14;
}

.visningsveksler .hjelpetekst { margin: 0; }

.visningsveksler-aktiv {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

/* Kolonneflyten strekker ellers knappen tvers over kortet (maalt til 528px paa
   560px bredde). En knapp saa bred leses som et felt. */
.visningsveksler > .knapp { align-self: flex-start; }

.visningsveksler-rad {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.visningsveksler-valg {
  flex: 1 1 14rem;
  min-width: 0;
  font-family: inherit;
  font-size: var(--t-liten);
  padding: 0.35rem 0.4rem;
  border: 1px solid var(--kant-mork);
  background: #fff;
  color: var(--tekst);
}

@media (max-width: 780px) {
  .vekslingsbanner { padding: 0.5rem 0.75rem; }
  /* Trykkflate. Alt annet i telefonvisningen staar paa 44px; en knapp som er
     eneste vei ut av en laant visning skal ikke vaere den minste paa sida. */
  .vekslingsbanner .knapp { min-height: 44px; }
  .visningsveksler-valg { min-height: 44px; flex-basis: 100%; }
  .visningsveksler .knapp { min-height: 44px; }
  /* Toppfeltet ruller bort paa telefon, og banneret med det. Den MOERKE
     logolinja staar sticky - den faar derfor den gule streken, slik at en
     glemt veksling er synlig ogsaa naar man har rullet nedover. */
  body.veksling-aktiv .sidefelt-logo { border-bottom: 3px solid var(--gul); }
}

/* --------------------------------------------------------------------------- */
/* Oppstartsbilde — introen som ligger over appen mens den starter             */
/* --------------------------------------------------------------------------- */
/* Markupen står i index.html (ikke i JS), tidsstyringen i js/oppstart.js.
   Bildet dekker hele skjermen i ca. --oppstart-tid, og tas ned når appen har
   meldt seg ferdig.

   REGEL FOR HELE BOLKEN: grunntilstanden i CSS-en er den FERDIGE tilstanden,
   og hver @keyframes animerer FRA en skjult startverdi med `both`. Da blir
   «prefers-reduced-motion» håndtert av én linje til slutt — slår man av
   animasjonene, står bildet igjen ferdig tegnet og lesbart, ikke usynlig. */

.oppstart {
  /* ÉN kilde til varigheten: js/oppstart.js leser denne verdien framfor å
     gjenta tallet, og framdriftsstolpen nedenfor bruker den som lengde. */
  --oppstart-tid: 3600ms;
  position: fixed;
  inset: 0;
  z-index: 2000;             /* over alt annet — høyeste ellers er 1200 */
  /* SKJULT som standard. Bildet vises først når app.js kaller visOppstart(),
     altså etter godkjent innlogging. At standarden er «skjult» og ikke
     «synlig, men fjernes straks» er poenget: en intro som males og deretter
     ryddes bort gir et mørkt glimt over innloggingssida ved hver last. */
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  cursor: pointer;           /* hele flaten hopper over introen */
  font-family: var(--font);
  color: #dce8f4;
  background: radial-gradient(circle at 50% 42%, #2b4360 0%, var(--aksent-mork) 46%, #0c141c 100%);
}

/* Klassen settes av visOppstart(). Animasjonene teller først ned fra dette
   øyeblikket — en `display: none`-animasjon står stille. */
.oppstart.oppstart-vis { display: flex; }

/* Uttoningen. Elementet fjernes fra DOM-en rett etterpå (se oppstart.js) — et
   heldekkende element med opacity 0 ville ellers blitt liggende over appen. */
.oppstart-ferdig {
  opacity: 0;
  transform: scale(1.06);
  pointer-events: none;
  transition: opacity 420ms ease, transform 560ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* Rutenettet — samme blåkopimønster som innloggingssida, men på mørk bunn og i
   sakte drift. Masken toner det ut mot kantene, slik at det ikke konkurrerer
   med teksten. */
.oppstart-rute {
  position: absolute;
  inset: -40px;
  background-image:
    linear-gradient(rgba(137, 178, 216, 0.10) 1px, transparent 1px),
    linear-gradient(90deg, rgba(137, 178, 216, 0.10) 1px, transparent 1px);
  background-size: 34px 34px;
  -webkit-mask-image: radial-gradient(circle at 50% 45%, #000 26%, transparent 76%);
  mask-image: radial-gradient(circle at 50% 45%, #000 26%, transparent 76%);
  animation: oppstart-rutedrift 6s linear infinite;
}
@keyframes oppstart-rutedrift { to { background-position: 34px 34px, 34px 34px; } }

/* Lyssveip nedover skjermen, to ganger. */
.oppstart-skann {
  position: absolute;
  left: 0;
  right: 0;
  top: -160px;
  height: 160px;
  background: linear-gradient(to bottom, transparent, rgba(150, 196, 240, 0.13), transparent);
  animation: oppstart-skann 2.3s cubic-bezier(0.4, 0, 0.25, 1) 150ms 2;
}
@keyframes oppstart-skann { to { transform: translateY(calc(100vh + 320px)); } }

/* Hjørnevinkler, som i et sikte. Tegnes ut fra hjørnet. */
.oppstart-hjorne {
  position: absolute;
  width: 46px;
  height: 46px;
  border: 0 solid var(--aksent);
  opacity: 0.85;
  animation: oppstart-hjorne 700ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.oppstart-hjorne-nv { top: 24px; left: 24px; border-top-width: 2px; border-left-width: 2px; }
.oppstart-hjorne-no { top: 24px; right: 24px; border-top-width: 2px; border-right-width: 2px; animation-delay: 80ms; }
.oppstart-hjorne-sv { bottom: 24px; left: 24px; border-bottom-width: 2px; border-left-width: 2px; animation-delay: 160ms; }
.oppstart-hjorne-so { bottom: 24px; right: 24px; border-bottom-width: 2px; border-right-width: 2px; animation-delay: 240ms; }
@keyframes oppstart-hjorne { from { width: 0; height: 0; opacity: 0; } }

.oppstart-midt {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 1rem;
}

/* ---- Emblemet: radarsveip, ringer og selve dronen ---- */
.oppstart-emblem {
  position: relative;
  width: clamp(120px, 30vw, 176px);
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  animation: oppstart-stig 800ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
.oppstart-sveip {
  position: absolute;
  inset: -18%;
  border-radius: 50%;
  opacity: 0.7;
  background: conic-gradient(from 0deg,
    color-mix(in srgb, var(--aksent) 62%, transparent) 0deg,
    transparent 62deg, transparent 360deg);
  -webkit-mask-image: radial-gradient(circle, transparent 33%, #000 41%, #000 66%, transparent 75%);
  mask-image: radial-gradient(circle, transparent 33%, #000 41%, #000 66%, transparent 75%);
  animation: oppstart-snurr 2.4s linear infinite;
}
@keyframes oppstart-snurr { to { transform: rotate(360deg); } }

/* To ringer som slår utover etter hverandre — som ping på et radarbilde. */
.oppstart-ring {
  position: absolute;
  inset: 3%;
  border: 1px solid color-mix(in srgb, var(--aksent) 75%, transparent);
  border-radius: 50%;
  opacity: 0;
  animation: oppstart-ping 2.6s ease-out infinite;
}
.oppstart-ring-2 { animation-delay: 1.3s; }
@keyframes oppstart-ping {
  0% { transform: scale(0.55); opacity: 0; }
  18% { opacity: 0.5; }
  100% { transform: scale(1.5); opacity: 0; }
}

.oppstart-drone {
  position: relative;
  width: 80%;
  height: auto;
  overflow: visible;
  color: #a9c9e8;
}
.drone-ramme path {
  fill: none;
  stroke: currentColor;
  stroke-width: 7;
  stroke-linecap: round;
  /* Armene tegnes utover fra midten. 40 dekker armlengden (~35,4). */
  stroke-dasharray: 40;
  animation: oppstart-tegn 600ms 120ms ease-out both;
}
@keyframes oppstart-tegn { from { stroke-dashoffset: 40; } }

.drone-kropp rect { fill: #17242f; stroke: currentColor; stroke-width: 4; }
.drone-linsering { fill: none; stroke: currentColor; stroke-width: 3; }
.drone-linse { fill: var(--aksent); animation: oppstart-blink 1.4s ease-in-out infinite; }
@keyframes oppstart-blink { 50% { fill: #eaf3fb; } }
.drone-strek { stroke: currentColor; stroke-width: 3; stroke-linecap: round; }

/* Rotorene. transform-box: fill-box gjør at hver gruppe snurrer om SIN EGEN
   midte — uten den roterer alle fire om SVG-ens origo, og dronen kaster seg
   rundt i stedet for å spinne opp. */
.drone-rotor { transform-box: fill-box; transform-origin: 50% 50%; }
.drone-rotor-h { animation: oppstart-rotor-h 4s linear both; }
.drone-rotor-v { animation: oppstart-rotor-v 4s linear both; }
.rotor-disk { fill: color-mix(in srgb, var(--aksent) 28%, transparent); }
.rotor-ring { fill: none; stroke: rgba(169, 201, 232, 0.4); stroke-width: 1.5; }
.rotor-blad { fill: currentColor; }
.rotor-nav { fill: #17242f; stroke: currentColor; stroke-width: 3; }
/* Oppspinn: sakte de første omdreiningene, deretter i ett kjør. Knekkpunktene
   er selve effekten — en jevn rotasjon ser ut som et hjul, ikke som en motor
   som starter.
   Varigheten (4s) skal være LENGER enn --oppstart-tid: slutter rotoranimasjonen
   først, står propellene bom stille de siste sekundene bildet vises. */
@keyframes oppstart-rotor-h {
  0% { transform: rotate(0deg); }
  20% { transform: rotate(90deg); }
  45% { transform: rotate(520deg); }
  70% { transform: rotate(1600deg); }
  100% { transform: rotate(4800deg); }
}
@keyframes oppstart-rotor-v {
  0% { transform: rotate(0deg); }
  20% { transform: rotate(-90deg); }
  45% { transform: rotate(-520deg); }
  70% { transform: rotate(-1600deg); }
  100% { transform: rotate(-4800deg); }
}

/* ---- Tekst ---- */
.oppstart-tittel {
  margin: 1.2rem 0 0;
  font-family: var(--font-overskrift);
  font-weight: 700;
  font-size: clamp(2.1rem, 8vw, 3.5rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  /* Sperringen legger luft etter SISTE tegn òg. Uten motvekten står ordet
     nesten en halv bokstav for langt til venstre i den midtstilte kolonnen. */
  padding-left: 0.16em;
  color: #fff;
  animation: oppstart-tittel 900ms 250ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
@keyframes oppstart-tittel {
  from { opacity: 0; letter-spacing: 0.45em; clip-path: inset(0 100% 0 0); }
  60% { opacity: 1; }
  to { opacity: 1; letter-spacing: 0.16em; clip-path: inset(0 0 0 0); }
}

.oppstart-strek {
  width: clamp(130px, 30vw, 240px);
  height: 2px;
  /* Luft nok til at streken leses som et skille og ikke som en understreking
     som har satt seg fast i tittelen. Målt: med 0,6rem over og 0,55rem under
     ble den 2px høye streken klemt inn i et 10px gap og forsvant. */
  margin: 0.95rem 0 0;
  /* Nesten heldekkende lys midtdel. Med et mykt forløp i BEGGE ender ble en
     2px strek borte på skjerm — det lyse partiet var da bare ~50px bredt. */
  background: linear-gradient(90deg, transparent, #eaf3fb 22%, #eaf3fb 78%, transparent);
  animation: oppstart-strek 700ms 600ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
@keyframes oppstart-strek { from { transform: scaleX(0); opacity: 0; } }

.oppstart-undertittel {
  margin: 0.8rem 0 0;
  font-size: var(--t-liten);
  letter-spacing: 0.32em;
  padding-left: 0.32em;
  text-transform: uppercase;
  color: rgba(220, 232, 244, 0.62);
  animation: oppstart-stig 700ms 780ms ease-out both;
}

/* Framdriftsstolpen bruker --oppstart-tid som lengde, og er derfor full i det
   øyeblikket minstetida er ute. */
.oppstart-stolpe {
  position: relative;
  width: clamp(160px, 34vw, 260px);
  height: 2px;
  margin-top: 1.9rem;
  background: rgba(255, 255, 255, 0.14);
  overflow: hidden;
}
.oppstart-fyll {
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  background: linear-gradient(90deg, var(--aksent), #d5e6f7);
  animation: oppstart-fyll var(--oppstart-tid) linear both;
}
@keyframes oppstart-fyll { from { width: 0; } }

.oppstart-status {
  margin: 0.6rem 0 0;
  font-size: var(--t-mikro);
  letter-spacing: 0.26em;
  padding-left: 0.26em;
  text-transform: uppercase;
  color: rgba(220, 232, 244, 0.5);
  animation: oppstart-stig 600ms 1s ease-out both;
}

@keyframes oppstart-stig { from { opacity: 0; transform: translateY(10px); } }

/* En ren uttoning, som erstatning for de bevegelsene som tas bort under. */
@keyframes oppstart-ton-inn { from { opacity: 0; } }

/* MINDRE BEVEGELSE, IKKE INGEN.
   Innstillingen handler om ting som FLYTTER seg over skjermen — det er den
   sorten som gir ubehag. Derfor forsvinner lyssveipet, rutedriften,
   radarsveipet og ringene, og alt som «stiger» inn blir en ren uttoning.
   Det som står på stedet blir igjen: rotorene som spinner opp, armene som
   tegnes, linsa som blinker og framdriftsstolpen som fyller seg. Det er
   forskjellen på et bilde som lever og et som ser ødelagt ut.

   Bolken sto tidligere som `animation: none !important` på ALT, og da var
   introen bom stille i 3,6 sekunder — meldt inn fra telefon, der iOS setter
   flagget både ved «Reduser bevegelse» og i strømsparing.

   `animation-name` alene: varighet, forsinkelse og fill-mode arves fra
   kortformen lenger oppe, så rekkefølgen elementene kommer inn i holdes. */
@media (prefers-reduced-motion: reduce) {
  .oppstart-skann,
  .oppstart-sveip,
  .oppstart-ring { display: none; }

  .oppstart-rute { animation: none; }

  .oppstart-hjorne,
  .oppstart-emblem,
  .oppstart-tittel,
  .oppstart-strek,
  .oppstart-undertittel,
  .oppstart-status { animation-name: oppstart-ton-inn; }

  /* Uttoningen ut beholdes, men uten at hele skjermen skalerer. */
  .oppstart-ferdig { transform: none; }
}

/* «Åpne / Last ned»-dialogen for vedlegg (vedlegg.js). */
.vedlegg-filnavn { font-weight: 600; word-break: break-word; margin: 0 0 0.5rem; }
.vedlegg-erstatt { margin-top: 1rem; padding-top: 0.8rem; border-top: 1px solid var(--kant, #ddd); }
.vedlegg-erstatt .hjelpetekst { margin: 0 0 0.6rem; }

/* Grønn hake foran datoen i leksjonslista: gjennomføringen er passert. */
.dato-med-hake { display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap; }
.gjennomfort-hake { display: inline-flex; color: var(--gronn); }
