/* Tingvi. Mobile first, 380px baseline, no framework.
   Targets: Lighthouse mobile >= 90, listing form usable one-handed, no modals. */

:root {
  --flate: #fdfcfa;
  --kort: #ffffff;
  --blekk: #1c1a17;
  --dempet: #6a635a;
  --kant: #e2ddd4;
  --aksent: #2f5d50;      /* granskog */
  --aksent-lys: #e8f0ec;
  --varsel: #8a4b1e;
  --varsel-lys: #fdf1e6;
  --feil: #97231d;
  --radius: 10px;
  --radius-kort: 16px;    /* cards and panels, softer than controls */
  --skygge: 0 10px 30px rgba(28, 26, 23, 0.07);
  --skygge-lav: 0 2px 8px rgba(28, 26, 23, 0.05);
  --tap: 44px;            /* minimum touch target */
  --spalte: 1280px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --flate: #16150f;
    --kort: #201e18;
    --blekk: #f2eee6;
    --dempet: #a79e91;
    --kant: #363228;
    --aksent: #8fc3b0;
    --aksent-lys: #23312c;
    --varsel: #e0a878;
    --varsel-lys: #2e2419;
    --feil: #e98b85;
    /* Shadows disappear on dark surfaces; borders carry the separation. */
    --skygge: 0 10px 30px rgba(0, 0, 0, 0.35);
    --skygge-lav: 0 2px 8px rgba(0, 0, 0, 0.3);
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--flate);
  color: var(--blekk);
  font: 400 17px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--aksent); }

.skip { position: absolute; left: -9999px; }
.skip:focus { left: 8px; top: 8px; background: var(--kort); padding: 8px; z-index: 10; }
.visuelt-skjult {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- topp ---------- */

.topp {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding: 12px 16px; border-bottom: 1px solid var(--kant); background: var(--kort);
}
.merke { font-weight: 700; font-size: 22px; text-decoration: none; letter-spacing: -0.01em; }
.sok { display: flex; flex: 1 1 100%; gap: 8px; order: 3; }
.sok input { flex: 1; min-width: 0; }

/* Wraps: four items plus a button does not fit one phone-width line. */
.toppmeny { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-left: auto; }
.toppmeny a { text-decoration: none; font-weight: 600; }

@media (min-width: 768px) {
  .sok { flex: 1 1 auto; max-width: 560px; order: 0; }
}

/* ---------- felles kontroller ---------- */

input, select, textarea, button {
  font: inherit;
  min-height: var(--tap);
  border-radius: var(--radius);
  border: 1px solid var(--kant);
  background: var(--kort);
  color: var(--blekk);
  padding: 10px 12px;
}
textarea { min-height: 120px; resize: vertical; }
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible,
a:focus-visible, .brikke input:focus-visible + span {
  outline: 3px solid var(--aksent); outline-offset: 2px;
}

.knapp {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); padding: 10px 18px;
  border-radius: var(--radius); border: 1px solid var(--aksent);
  background: var(--kort); color: var(--aksent);
  text-decoration: none; font-weight: 600; cursor: pointer;
}
.knapp.primar { background: var(--aksent); color: var(--flate); border-color: var(--aksent); }

/* ---------- annonseskjema ---------- */

.annonseskjema { max-width: 640px; margin: 0 auto; padding: 16px; }

.steg {
  border: 1px solid var(--kant); border-radius: var(--radius-kort);
  background: var(--kort); padding: 18px; margin: 0 0 16px;
  box-shadow: var(--skygge-lav);
}
.steg legend { font-weight: 700; padding: 0 6px; }
.steg.viktig { border-color: var(--aksent); }

.annonseskjema label { display: block; margin: 14px 0 6px; font-weight: 600; }
.annonseskjema input[type="text"],
.annonseskjema input[type="url"],
.annonseskjema input[type="number"],
.annonseskjema select,
.annonseskjema textarea { width: 100%; }

.avkrysning, .valg {
  display: flex; gap: 10px; align-items: flex-start;
  font-weight: 400; margin: 12px 0; min-height: var(--tap);
}
.avkrysning input, .valg input { min-height: 22px; width: 22px; height: 22px; margin-top: 2px; }

.hjelp { margin: 6px 0 0; color: var(--dempet); font-size: 15px; }
.fin { color: var(--dempet); font-size: 14px; }

.feil { margin: 6px 0 0; color: var(--feil); font-weight: 600; }
.feil.samlet {
  background: var(--varsel-lys); border: 1px solid var(--varsel);
  border-radius: var(--radius); padding: 12px; margin-bottom: 16px;
}

.advarsel {
  background: var(--varsel-lys); border-left: 4px solid var(--varsel);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 12px 14px; margin: 16px 0 0; font-size: 15px;
}

/* Kamera først, ikke filvelger. */
.kamera {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; min-height: 140px; cursor: pointer;
  border: 2px dashed var(--kant); border-radius: var(--radius);
  background: var(--aksent-lys); color: var(--aksent); font-weight: 600;
}
/* Only hidden once skjema.js has marked the page as scripted. Hiding it
   unconditionally also hid the browser's own «3 files selected», so choosing a
   photo changed nothing on screen — see static/skjema.js. */
.js .kamera input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.kamera input { margin-top: 8px; }

.valgte-bilder {
  list-style: none; margin: 10px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 12px;
}
.valgte-bilder li {
  display: flex; flex-direction: column; gap: 4px;
  max-width: 120px; font-size: 13px; color: var(--dempet);
}
.valgte-bilder img {
  width: 120px; height: 120px; object-fit: cover; border-radius: var(--radius);
}
.valgte-bilder span { overflow-wrap: anywhere; }

/* Tap-brikker slår nedtrekksmeny på mobil: ett trykk, ikke tre. */
.brikker { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.brikke input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.brikke span {
  display: inline-flex; align-items: center; min-height: var(--tap);
  padding: 8px 14px; border: 1px solid var(--kant); border-radius: 999px;
  background: var(--kort); cursor: pointer;
}
.brikke input:checked + span {
  background: var(--aksent); color: var(--flate); border-color: var(--aksent);
}
.egenskap { margin: 18px 0; }
.egenskap .etikett { display: block; font-weight: 600; margin-bottom: 4px; }
.egenskap input[type="text"] { width: 100%; }
.egenskap .hjelp { margin-top: 4px; }

/* ---------- annonse ---------- */

.annonse { max-width: 720px; margin: 0 auto; padding: 16px; }
.annonse h1 { font-size: 26px; line-height: 1.25; margin: 8px 0; }
.annonse .pris { font-size: 22px; font-weight: 700; margin: 4px 0; }
.bilder { display: grid; gap: 8px; }
/* Capped so the photo cannot own the whole first screen. Uncapped, a 4:3 shot
   in the 720px column is ~517px tall and pushes the title, the price and the
   «kjøp»-button below the fold on a laptop — the buyer scrolls before learning
   what the thing is or costs.

   `contain`, not `cover`: cropping decides for the seller which part of their
   photo matters, and on a listing the whole object is usually the point. A tall
   photo therefore gets bars at the sides rather than having its top and bottom
   cut off. The background is the border grey so those bars read as frame, not
   as a broken image. */
.bilder img {
  width: 100%; height: auto; max-height: 60vh;
  object-fit: contain; background: var(--kant);
  border-radius: var(--radius);
}
.beskrivelse p { margin: 0 0 12px; }

/* Kun definisjonslista på annonsesiden. Skjemafeltsettet deler klassenavn,
   og arvet et todelt rutenett som klemte inputfeltene sammen. */
dl.egenskaper {
  display: grid; grid-template-columns: auto 1fr; gap: 6px 16px;
  border-top: 1px solid var(--kant); padding-top: 16px; margin: 20px 0;
}
dl.egenskaper dt { color: var(--dempet); }
dl.egenskaper dd { margin: 0; }

.merkelapp {
  display: inline-block; padding: 3px 10px; border-radius: 999px;
  font-size: 13px; font-weight: 700; letter-spacing: 0.01em;
}
.merkelapp.betalt { background: var(--varsel-lys); color: var(--varsel); }
.merkelapp.ny { background: var(--aksent-lys); color: var(--aksent); }
.merkelapp.tier-business { background: var(--aksent-lys); color: var(--aksent); }
.merkelapp.tier-hobby { background: var(--kant); color: var(--dempet); }

.selger, .angrerett {
  border: 1px solid var(--kant); border-radius: var(--radius-kort);
  background: var(--kort); padding: 18px; margin: 20px 0;
  box-shadow: var(--skygge-lav);
}
.selger h2, .angrerett h2 { font-size: 18px; margin: 0 0 10px; }
.ansvarslinje { border-top: 1px solid var(--kant); padding-top: 12px; margin-top: 12px; }
.angrerett.privat { border-left: 4px solid var(--dempet); }
.angrerett.unntatt { border-left: 4px solid var(--varsel); }
.angrerett.full { border-left: 4px solid var(--aksent); }
.selgerlinje { color: var(--dempet); font-size: 15px; }

/* ---------- rutenett ---------- */

/* `auto-fit` with a floor, not `repeat(N, 1fr)`. A fixed count divides whatever
   width it is handed, so in a narrow parent it makes N unreadable slivers
   instead of fewer columns — which is exactly what happened when the search
   results ended up in the 280px sidebar: four cards at 62px each, on screen and
   illegible. A minimum column width cannot fail that way wherever it lands. */
.rutenett {
  display: grid; gap: 12px; padding: 16px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
@media (min-width: 768px)  { .rutenett { grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); } }
@media (min-width: 1200px) {
  .rutenett { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); max-width: 1280px; margin: 0 auto; }
}

.kort {
  position: relative; background: var(--kort);
  border: 1px solid var(--kant); border-radius: var(--radius-kort);
  overflow: hidden; box-shadow: var(--skygge-lav);
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.kort:hover { box-shadow: var(--skygge); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) { .kort, .kort:hover { transition: none; transform: none; } }
.kort a { display: block; text-decoration: none; color: inherit; }
.kort img, .kort .bilde-mangler { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }
.kort .bilde-mangler { display: block; background: var(--kant); }
.kort h3 { font-size: 16px; margin: 10px 10px 4px; line-height: 1.3; }
.kort .pris { font-weight: 700; margin: 0 10px; }
.kort .sted { color: var(--dempet); font-size: 14px; margin: 2px 10px 10px; }
/* One row in the corner, so badges sit beside each other instead of on top of
   each other. They were each `position: absolute` at the same coordinates, and
   the second one drawn simply covered the first. */
.kort .kortmerker {
  position: absolute; top: 8px; left: 8px;
  display: flex; flex-wrap: wrap; gap: 6px;
}

/* ---------- nye butikker ---------- */

/* Same auto-fit rule as `.rutenett`, for the same reason: a fixed column count
   divides whatever width it is given, which is how the card grid once became
   four 62px slivers inside a sidebar. */
.butikkrad {
  display: grid; gap: 12px; padding: 0 16px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.butikkort {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: var(--kort); border: 1px solid var(--kant);
  border-radius: var(--radius-kort); padding: 14px;
  text-decoration: none; color: inherit;
  box-shadow: var(--skygge-lav);
  transition: box-shadow 120ms ease, transform 120ms ease;
}
.butikkort:hover { box-shadow: var(--skygge); transform: translateY(-2px); }
@media (prefers-reduced-motion: reduce) {
  .butikkort, .butikkort:hover { transition: none; transform: none; }
}
.butikkort .logo {
  width: 48px; height: 48px; border-radius: 50%; object-fit: cover;
  margin-bottom: 6px;
}
.butikkort .logo.tom {
  display: flex; align-items: center; justify-content: center;
  background: var(--aksent-lys); color: var(--aksent);
  font-weight: 700; font-size: 20px;
}
.butikkort .navn { font-weight: 600; }
.butikkort .kort {
  color: var(--dempet); font-size: 14px; line-height: 1.35;
  /* Two lines, so one seller's long tagline cannot make its tile taller than
     every other tile on the row. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.butikkort .meta { color: var(--dempet); font-size: 13px; margin-top: 4px; }
.butikkort .merkelapp { margin-top: 8px; }

/* «Ny butikk» beside the shop's name, in the flow of the line rather than over
   the photo. Muted on purpose: it is context about the seller, not a claim
   about the item, and it must not compete with the paid-placement disclosure. */
.nybutikk {
  display: inline-block; margin-left: 6px;
  padding: 1px 7px; border-radius: 999px;
  background: var(--aksent-lys); color: var(--aksent);
  font-size: 12px; font-weight: 600; vertical-align: baseline;
}

/* ---------- bunn ---------- */

.bunn { border-top: 1px solid var(--kant); margin-top: 32px; padding: 20px 16px 40px; }
.bunn nav { display: flex; flex-wrap: wrap; gap: 16px; margin-bottom: 10px; }

/* ---------- avtaletekst ---------- */

.avtaletekst { max-width: 100%; }
.avtaletekst h1 { font-size: 24px; line-height: 1.25; }
.avtaletekst h2 { font-size: 19px; margin-top: 28px; }
.avtaletekst h3 { font-size: 17px; margin-top: 20px; }
.avtaletekst p { margin: 0 0 12px; }
.vilkar .steg.viktig { position: sticky; bottom: 12px; }

/* ---------- sok og forside ---------- */

.anbefalinger { padding: 16px 16px 0; max-width: 1280px; margin: 0 auto; }
.anbefalinger h1 { font-size: 20px; margin: 0; }
.tomt { padding: 24px 16px; color: var(--dempet); }

.sokeside { max-width: 1280px; margin: 0 auto; }
.treffhode { padding: 16px 16px 0; }
.treffhode h1 { font-size: 20px; margin: 0 0 4px; }

.filtre { padding: 16px; display: grid; gap: 12px; border-bottom: 1px solid var(--kant); }
.filtre fieldset {
  border: 1px solid var(--kant); border-radius: var(--radius);
  background: var(--kort); padding: 12px 14px; margin: 0;
}
.filtre legend { font-weight: 700; padding: 0 6px; }
.filtre label { display: block; margin: 10px 0 4px; font-weight: 600; }
.filtre input[type="text"], .filtre select { width: 100%; }
.prisrom { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: end; }
.fasettgruppe { margin: 12px 0; }

.fasetter { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 4px; }
.fasetter a {
  display: flex; justify-content: space-between; gap: 12px;
  min-height: var(--tap); align-items: center; text-decoration: none;
}
.fasetter .antall { color: var(--dempet); font-variant-numeric: tabular-nums; }

.kategoriliste { padding: 24px 16px; max-width: 1280px; margin: 0 auto; }
.kategoriliste h2 { font-size: 18px; }
.kategoriliste ul { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.kategoriliste a {
  display: inline-flex; align-items: center; min-height: var(--tap);
  padding: 8px 14px; border: 1px solid var(--kant); border-radius: 999px;
  background: var(--kort); text-decoration: none;
}

.sidevelger {
  display: flex; gap: 12px; align-items: center; justify-content: center;
  padding: 24px 16px;
}

@media (min-width: 900px) {
  /* Every child is placed explicitly. Auto-placement put «Lagre dette søket»
     into the wide cell and pushed the results down into the 280px sidebar
     column, where `.rutenett`'s four equal columns became 62px each — the
     results were on the page, just unreadably small and under the filters.
     Leaving placement implicit means adding one element anywhere in this form
     silently reshuffles the page. */
  .sokeside {
    display: grid; grid-template-columns: 280px 1fr; gap: 0 24px; align-items: start;
  }
  .treffhode  { grid-column: 1 / -1; grid-row: 1; }
  .filtre     { grid-column: 1; grid-row: 2; border-bottom: 0;
                border-right: 1px solid var(--kant); align-content: start; }
  .lagresok   { grid-column: 1; grid-row: 3; }
  .resultater { grid-column: 2; grid-row: 2 / span 2; }
}

/* ---------- meldinger og admin ---------- */

.grunnlag {
  margin: 12px 0; padding: 10px 14px; border-left: 4px solid var(--kant);
  background: var(--flate); white-space: pre-wrap;
}

.admin { max-width: 900px; margin: 0 auto; padding: 16px; }
.admin h1 { font-size: 22px; }

.melding {
  border: 1px solid var(--kant); border-radius: var(--radius);
  background: var(--kort); padding: 16px; margin: 16px 0;
}
.melding.haster { border-color: var(--varsel); }
.melding.forfalt { border-color: var(--feil); border-width: 2px; }
.melding header { display: flex; justify-content: space-between; gap: 12px; }
.melding .frist { font-weight: 700; }
.melding.haster .frist { color: var(--varsel); }
.melding.forfalt .frist { color: var(--feil); }
.melding .ref { color: var(--dempet); }
.melding dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; margin: 12px 0; }
.melding dt { color: var(--dempet); }
.melding dd { margin: 0; overflow-wrap: anywhere; }
.melding textarea { width: 100%; }
.handlinger { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

.logg { width: 100%; border-collapse: collapse; font-size: 15px; }
.logg caption { text-align: left; margin-bottom: 8px; }
.logg th, .logg td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--kant); }
.logg .url { overflow-wrap: anywhere; }

/* ---------- hjelpesider ---------- */

.hjelpeside { max-width: 720px; margin: 0 auto; padding: 16px 16px 40px; }
.hjelpeside h1 { font-size: 26px; line-height: 1.25; }
.hjelpeside h2 { font-size: 19px; margin-top: 32px; }
.hjelpeside .ingress { font-size: 18px; }

.lisensliste { margin: 16px 0; }
.lisensliste dt {
  font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  margin-top: 16px;
}
.lisensliste dd { margin: 4px 0 0; }

.lisenstabell { width: 100%; border-collapse: collapse; margin: 16px 0; }
.lisenstabell th, .lisenstabell td {
  text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--kant);
}
.lisenstabell .ja { color: var(--aksent); font-weight: 600; }
.lisenstabell .nei { color: var(--feil); font-weight: 700; }

/* Honeypot: off-screen rather than display:none, which some bots detect. */
.lokkefelt {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}
.omtale { color: var(--dempet); }

/* ---------- mine annonser ---------- */

.mine { max-width: 800px; margin: 0 auto; padding: 16px; }
.annonseliste { list-style: none; padding: 0; margin: 16px 0; }
.annonseliste .rad {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  justify-content: space-between;
  border: 1px solid var(--kant); border-radius: var(--radius);
  background: var(--kort); padding: 14px; margin-bottom: 10px;
}
.annonseliste .hva a { font-weight: 600; }
.annonseliste .tilstand { margin: 4px 0 0; color: var(--dempet); font-size: 15px; }
.annonseliste .radhandlinger { display: flex; gap: 8px; flex-wrap: wrap; }
.rad.status-expired { border-left: 4px solid var(--varsel); }
.rad.status-paused { border-left: 4px solid var(--dempet); }
.rad.status-removed { opacity: 0.6; }

/* ---------- butikkside ---------- */

.butikk { max-width: 1280px; margin: 0 auto; }

.butikkhode { position: relative; margin-bottom: 16px; }
.butikkhode .banner {
  width: 100%; aspect-ratio: 3 / 1; object-fit: cover;
  border-bottom: 1px solid var(--kant);
}
.butikkhode.uten-banner { padding-top: 16px; }

.identitet {
  display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end;
  padding: 0 16px; margin-top: -44px;
}
.butikkhode.uten-banner .identitet { margin-top: 0; }
.identitet .logo {
  width: 88px; height: 88px; border-radius: 50%; object-fit: cover;
  border: 3px solid var(--flate); background: var(--kort); flex: none;
}
.identitet .logo.tom {
  display: flex; align-items: center; justify-content: center;
  font-size: 34px; font-weight: 700; color: var(--aksent);
  background: var(--aksent-lys);
}
.identitet .navn { flex: 1 1 220px; }
.identitet h1 { font-size: 24px; margin: 0; line-height: 1.2; }
.identitet .kort { margin: 4px 0 0; color: var(--dempet); }
.identitet .merker { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; }
.identitet .rediger { flex: none; }
.merkelapp.bestilling { background: var(--aksent-lys); color: var(--aksent); }

.blokker {
  display: grid; gap: 12px; padding: 0 16px;
  grid-template-columns: 1fr;
}
@media (min-width: 700px)  { .blokker { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .blokker { grid-template-columns: repeat(4, 1fr); } }

.blokk {
  border: 1px solid var(--kant); border-radius: var(--radius-kort);
  background: var(--kort); padding: 16px; box-shadow: var(--skygge-lav);
}
.blokk h2 { font-size: 16px; margin: 0 0 8px; }
.blokk p { margin: 0 0 8px; }
.blokk .etikett { color: var(--dempet); font-size: 14px; margin: 10px 0 4px; }

.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; padding: 0; margin: 0; }
.chips li {
  padding: 4px 10px; border-radius: 999px; font-size: 14px;
  background: var(--flate); border: 1px solid var(--kant);
}

.lenker { padding: 16px; }
.lenker h2 { font-size: 16px; margin: 0 0 8px; }
.lenkekort {
  display: inline-flex; flex-direction: column; gap: 2px;
  border: 1px solid var(--kant); border-radius: var(--radius);
  background: var(--kort); padding: 10px 14px; margin: 0 8px 8px 0;
  text-decoration: none; min-height: var(--tap); justify-content: center;
}
.lenkekort .hva { font-weight: 600; }
.lenkekort .hvor { color: var(--dempet); font-size: 14px; overflow-wrap: anywhere; }

/* Heading and «se alle» on one line, and wrapping rather than colliding on a
   narrow phone — the heading is short but a shop name is not always. */
.butikkvarer {
  padding: 8px 16px 0;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px 16px; flex-wrap: wrap;
}
.butikkvarer h2 { font-size: 18px; margin: 0; }
.butikkvarer .antall { color: var(--dempet); font-weight: 400; }
.butikkvarer .se-alle { font-size: 14px; white-space: nowrap; }

/* Under the grid, where it is a destination rather than an aside. Centred and
   given the button's hit area, since this is the one on a phone that gets
   thumbed. */
.se-alle-under { margin: 16px 0 0; text-align: center; }

.butikkvarer-side { padding: 0 16px; }
.butikkvarer-side h1 { font-size: 22px; margin: 4px 0 2px; }
.tilbake { margin: 0; font-size: 14px; }
.sideveksling {
  display: flex; justify-content: space-between; gap: 12px;
  margin: 24px 0 8px;
}
/* Keeps «Neste» on the right when «Forrige» is absent, i.e. on page one. */
.sideveksling .knapp:only-child { margin-left: auto; }

.forhandsvis { border-radius: var(--radius); margin: 8px 0; object-fit: cover; }
.forhandsvis.logo { width: 88px; height: 88px; border-radius: 50%; }
.forhandsvis.banner { width: 100%; max-width: 400px; aspect-ratio: 3 / 1; }

/* ---------- farlige handlinger ---------- */

.steg.farlig { border-color: var(--feil); }
.steg.farlig legend { color: var(--feil); }
.knapp.farlig { border-color: var(--feil); color: var(--feil); }
.knapp.farlig:hover { background: var(--feil); color: var(--flate); }
.annonseskjema ul { margin: 8px 0; padding-left: 20px; }
.annonseskjema li { margin-bottom: 6px; }

/* ---------- sporsmal og svar ---------- */

.sporsmal {
  border: 1px solid var(--kant); border-radius: var(--radius-kort);
  background: var(--kort); padding: 18px; margin: 20px 0;
  box-shadow: var(--skygge-lav);
}
.sporsmal h2 { font-size: 18px; margin: 0 0 10px; }
.trad { list-style: none; padding: 0; margin: 0 0 16px; }
.trad .q { border-top: 1px solid var(--kant); padding: 12px 0; }
.trad .q:first-child { border-top: 0; }
.trad .hvem { color: var(--dempet); font-size: 14px; margin: 0 0 4px; }
.trad .tekst p { margin: 0 0 6px; }
.trad .svar {
  margin: 10px 0 0 14px; padding-left: 12px;
  border-left: 3px solid var(--aksent);
}
.trad .venter { color: var(--dempet); font-size: 15px; margin: 6px 0 0; }
.svarskjema textarea, .spormskjema textarea { width: 100%; }
.skjulskjema { margin-top: 6px; }
.knapp.liten { min-height: 34px; padding: 4px 10px; font-size: 14px; font-weight: 400; }

/* ---------- forside ---------- */

/* Structure borrowed from Norm's reference layout; palette unchanged. There is
   deliberately no cart icon anywhere: Tingvi has no checkout, and a cart in the
   chrome would imply exactly the protection §1.4 says never to imply. */

.helt {
  background: linear-gradient(180deg, var(--aksent-lys) 0%, var(--flate) 100%);
  border-bottom: 1px solid var(--kant);
  padding: 28px 16px 24px;
}
.helt-inner { max-width: 720px; margin: 0 auto; text-align: center; }
.helt .stikk {
  display: inline-block; margin: 0 0 10px; padding: 4px 12px;
  border-radius: 999px; background: var(--kort); border: 1px solid var(--kant);
  font-size: 14px; font-weight: 600; color: var(--aksent);
}
.helt h1 { font-size: 28px; line-height: 1.2; margin: 0 0 8px; letter-spacing: -0.02em; }
.helt .under { color: var(--dempet); margin: 0 0 18px; font-size: 17px; }

.heltsok { display: flex; gap: 8px; }
.heltsok input {
  flex: 1; min-width: 0; font-size: 17px;
  border-radius: var(--radius-kort); box-shadow: var(--skygge-lav);
}
.heltsok button { border-radius: var(--radius-kort); }

.snarveier {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  margin-top: 14px;
}
/* The full category list, which reads as a list and so starts at the left
   margin — unlike the handful of shortcuts under the hero, which are centred.
   This was an inline `style` attribute, which the Content-Security-Policy
   (`style-src 'self'`, no unsafe-inline) blocked outright: the rule had never
   once applied, and every homepage load logged a violation. */
.snarveier.venstre { justify-content: flex-start; }
.snarveier a {
  display: inline-flex; align-items: center; min-height: 38px;
  padding: 6px 14px; border-radius: 999px;
  background: var(--kort); border: 1px solid var(--kant);
  text-decoration: none; color: var(--blekk); font-size: 15px;
}
.snarveier a:hover { border-color: var(--aksent); color: var(--aksent); }

/* Three claims, all of them true and all of them things FINN and Epla cannot
   say. Nothing here promises buyer protection. */
.tillit {
  display: grid; gap: 10px; padding: 16px;
  max-width: var(--spalte); margin: 0 auto;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) { .tillit { grid-template-columns: repeat(3, 1fr); } }
.tillit div {
  background: var(--kort); border: 1px solid var(--kant);
  border-radius: var(--radius-kort); padding: 14px 16px;
  box-shadow: var(--skygge-lav);
}
.tillit strong { display: block; }
.tillit span { color: var(--dempet); font-size: 15px; }

.seksjon { max-width: var(--spalte); margin: 0 auto; padding: 8px 16px 0; }
.seksjonshode {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 4px;
}
.seksjonshode h2 { font-size: 20px; margin: 20px 0 0; }
.seksjonshode a { font-size: 15px; }

.selgerkall {
  max-width: var(--spalte); margin: 28px auto 0; padding: 0 16px;
}
.selgerkall > div {
  background: var(--aksent); color: var(--flate);
  border-radius: var(--radius-kort); padding: 24px 20px; text-align: center;
}
.selgerkall h2 { margin: 0 0 6px; font-size: 21px; }
.selgerkall p { margin: 0 0 16px; opacity: 0.9; }
.selgerkall .knapp {
  background: var(--flate); color: var(--aksent); border-color: var(--flate);
}

.lagresok { padding: 0 16px 16px; }
@media (min-width: 900px) { .lagresok { padding: 0; } }

/* ---------- bilder på redigeringsskjemaet ---------- */

.bildeliste {
  list-style: none; margin: 12px 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 16px;
}
.bildeliste li { display: flex; flex-direction: column; gap: 6px; max-width: 140px; }
.bildeliste img { width: 120px; height: 120px; object-fit: cover; border-radius: var(--radius); }
.bildeliste .avkrysning { margin: 0; font-size: 14px; }
.eierhandlinger { margin: 20px 0; }

/* ---------- driftsoversikt ---------- */
/* One column at every width. The operator reads this on a phone, and a layout
   that reflows into columns on a laptop would put the deadline queue somewhere
   other than first. */

.admin { max-width: 640px; margin: 0 auto; padding: 16px; }
.admin h1 { margin: 0 0 20px; }
.admin section { margin: 0 0 32px; }
.admin h2 {
  font-size: 15px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--dempet); margin: 0 0 12px;
}

.admin .kort { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.admin .kort li { border-radius: var(--radius-kort); border: 1px solid var(--kant); background: var(--kort); }
.admin .kort a {
  display: flex; flex-direction: column; gap: 2px;
  padding: 16px; min-height: var(--tap); text-decoration: none; color: inherit;
}
.admin .kort .tall { font-size: 32px; font-weight: 600; line-height: 1.1; }
.admin .kort .etikett { color: var(--dempet); }
.admin .kort .frist { font-size: 14px; }
/* Zero is the normal state and must not look like an alarm; anything above it
   should be visible from across the room. */
.admin .kort li.haster { border-color: var(--varsel); background: var(--varsel-lys); }
.admin .kort li.haster .tall, .admin .kort li.haster .frist { color: var(--varsel); }

.tall-tabell { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.tall-tabell th, .tall-tabell td { padding: 8px 4px; border-bottom: 1px solid var(--kant); text-align: right; }
.tall-tabell thead th { color: var(--dempet); font-weight: 500; font-size: 14px; }
.tall-tabell tbody th { text-align: left; font-weight: 400; }

.noekkeltall { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; font-variant-numeric: tabular-nums; }

.annonseliste { list-style: none; margin: 0; padding: 0; }
.annonseliste li {
  display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline;
  padding: 10px 0; border-bottom: 1px solid var(--kant);
}
.annonseliste .butikk, .annonseliste time { color: var(--dempet); font-size: 14px; }
/* Titles run to 140 characters and shop names to 80, neither of which has
   to contain a space. Same failure as the click table: one unbroken word
   takes the whole page sideways. */
.annonseliste a { flex: 1 1 auto; min-width: 50%; overflow-wrap: anywhere; }

.admin .rolig { color: var(--dempet); }
.admin .haster { color: var(--varsel); font-weight: 500; }
.admin .snarveier ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 16px; }

/* Owner-only, on their own shop page. Reads as information, not as an alert:
   zero clicks is the normal state for a new shop and must not look like a
   problem. */
.klikkteller {
  margin: 0 16px 20px; padding: 12px 16px;
  border-radius: var(--radius); background: var(--aksent-lys); color: var(--blekk);
}
@media (min-width: 900px) { .klikkteller { margin-left: 0; margin-right: 0; } }
.klikkteller .hovedtall { margin: 0; }
/* The box already has padding; the summary only needs to stay a tap target. */
.klikkteller .sammenleggbar > summary { padding: 4px 0; }
.klikkteller .sammenleggbar > summary .hovedtall { color: inherit; font-size: inherit; }

/* preserveAspectRatio="none" on the SVG, so the viewBox stretches to whatever
   width the column is and the bars keep their relative heights. */
.klikkteller .stolper {
  display: block; width: 100%; height: 60px; margin: 12px 0 4px;
}
.klikkteller .stolper rect { fill: var(--aksent); }
/* A zero day is a sliver on the baseline, not a missing bar: a gap would read
   as «no data» when it means «no clicks». */
.klikkteller .stolper rect.tom { fill: var(--kant); }

.klikkteller .akse {
  display: flex; justify-content: space-between;
  margin: 0; font-size: 12px; color: var(--dempet);
}
.klikkteller .sammenlikning { margin: 8px 0 0; font-size: 14px; }
.klikkteller .sammenlikning.retning-opp { color: var(--aksent); font-weight: 500; }
.klikkteller .sammenlikning.retning-ned { color: var(--varsel); }

/* Per-listing click count on Mine annonser. Zero is the normal state for a new
   listing, so it stays quiet; a listing that is working earns the accent. */
.mine .klikk { margin: 4px 0 0; font-size: 14px; color: var(--dempet); }
.mine .klikk.har-klikk { color: var(--aksent); font-weight: 500; }
.mine .klikk.mangler-lenke { font-style: italic; }

/* Per-shop clicks on the dashboard. Shop names allow 80 characters and nothing
   forces a space in them, so the name cell must be allowed to break mid-word:
   measured at 375 px, one unbroken 51-character name pushed the table to 502 px
   and took the whole page sideways with it. */
/* Sparkline under the label rather than in a fifth column: at 375 px there is
   no room for one, and the label already wraps. */
.trafikk .tall-tabell tbody th { line-height: 1.3; }
.sparkelinje {
  display: block; width: 100%; max-width: 160px; height: 18px; margin: 4px 0 2px;
}
.sparkelinje rect { fill: var(--aksent); }
.sparkelinje rect.tom { fill: var(--kant); }

.klikk-per-butikk .tall-tabell tbody th,
.klikk-per-annonse .tall-tabell tbody th {
  font-weight: 400; overflow-wrap: anywhere;
}
.klikk-per-butikk .merkelapp.liten,
.klikk-per-annonse .merkelapp.liten {
  font-size: 11px; padding: 1px 6px; margin-left: 6px; vertical-align: 1px;
}
.stille-butikker .annonseliste a { min-width: 0; }
/* Shop name under the title, same relationship as in Nyeste annonser. */
.klikk-per-annonse .butikk { display: block; color: var(--dempet); font-size: 13px; }

/* Owner-only click count under a card in the shop grid. The wrapper is a grid
   item in place of the card, so the card keeps its own sizing. */
.kort-med-tall { display: flex; flex-direction: column; gap: 4px; }
.kort-med-tall .klikk { margin: 0; font-size: 13px; color: var(--dempet); }
.kort-med-tall .klikk.har-klikk { color: var(--aksent); font-weight: 500; }

/* Owner-only block on the listing page. Reads as information, not as a control:
   the edit button below it is the only thing here to act on. */
.eierhandlinger .klikk {
  margin: 0 0 12px; padding: 10px 14px; border-radius: var(--radius);
  background: var(--kant); color: var(--dempet); font-size: 14px;
}
.eierhandlinger .klikk.har-klikk { background: var(--aksent-lys); color: var(--aksent); }
.eierhandlinger .klikk a { color: inherit; }

/* ---------- sammenleggbar seksjon ---------- */
/* The h2 stays inline rather than the summary becoming a flexbox: `display:
   flex` on a <summary> removes the disclosure triangle in Chrome and Safari,
   and a collapsible panel with no affordance is just a heading that hides
   things. Inline keeps the native marker doing its job. */

.sammenleggbar > summary {
  cursor: pointer;
  padding: 10px 0;
  min-height: var(--tap);
  box-sizing: border-box;
}
.sammenleggbar > summary h2 { display: inline; }
.sammenleggbar > summary .sammendrag {
  display: block;
  margin-left: 1.1em;              /* clears the marker */
  color: var(--dempet);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.sammenleggbar > summary:focus-visible {
  outline: 2px solid var(--aksent);
  outline-offset: 2px;
  border-radius: var(--radius);
}
/* Same rule the rest of the site follows: no motion for people who asked for
   none. There is no animation here anyway — this is a guard for later. */
@media (prefers-reduced-motion: reduce) {
  .sammenleggbar, .sammenleggbar * { transition: none !important; animation: none !important; }
}

/* ---------- moderasjon ---------- */

.statusfilter { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.statusfilter a {
  padding: 6px 12px; border-radius: 999px; border: 1px solid var(--kant);
  text-decoration: none; color: var(--dempet); font-size: 14px;
}
.statusfilter a.valgt { background: var(--aksent); border-color: var(--aksent); color: #fff; }

.moderasjonsliste { list-style: none; margin: 0 0 16px; padding: 0; }
.moderasjonsliste .rad {
  padding: 14px 0; border-bottom: 1px solid var(--kant);
  display: grid; gap: 10px;
}
.moderasjonsliste .hva a { overflow-wrap: anywhere; }
.moderasjonsliste .butikk, .moderasjonsliste .tilstand {
  display: block; color: var(--dempet); font-size: 14px;
}
/* A listing already taken down should not read like a live one. */
.moderasjonsliste .status-removed .hva > a { text-decoration: line-through; }

.moderasjon { display: grid; gap: 8px; }
.moderasjon label { display: grid; gap: 4px; font-size: 14px; color: var(--dempet); }
.moderasjon select, .moderasjon input[type="text"] { min-height: var(--tap); }
/* Destructive and reversible, so warning-coloured rather than alarming: the
   seller can be told and the listing can be put back. */
.knapp.fare { background: var(--varsel-lys); border-color: var(--varsel); color: var(--varsel); }

/* ---------- tofaktor ---------- */
.qr { display: block; width: 220px; height: 220px; margin: 12px 0; background: #fff; }
.noekkel code {
  display: inline-block; padding: 8px 12px; background: var(--kant);
  border-radius: var(--radius); font-size: 16px; letter-spacing: 0.08em;
  overflow-wrap: anywhere;
}
.reservekoder {
  list-style: none; margin: 16px 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 8px;
}
.reservekoder code {
  display: block; padding: 10px; background: var(--kort);
  border: 1px solid var(--kant); border-radius: var(--radius);
  text-align: center; letter-spacing: 0.06em;
}

/* Maker first on the card, place after it. */
.kort .butikknavn { font-weight: 600; color: var(--blekk); }

/* Sign out sits in the top menu and must not look like a primary action. */
.toppmeny .loggut { margin: 0; }
.toppmeny .loggut button {
  background: none; border: 0; padding: 0; min-height: 0;
  font: inherit; font-weight: 600; color: var(--dempet); cursor: pointer;
}
.toppmeny .loggut button:hover { color: var(--blekk); text-decoration: underline; }

/* Delete, behind a disclosure. Destructive and irreversible, so the button does
   not exist until the seller has opened it. */
.moderasjon .slett, .radhandlinger .slett { margin-top: 4px; }
.radhandlinger .slett > summary {
  cursor: pointer; color: var(--feil); font-size: 14px; min-height: var(--tap);
  display: list-item; padding: 10px 0;
}
.radhandlinger .slett .hjelp { margin: 0 0 8px; }

/* Category chip on a card. A sibling of the card's link rather than a child —
   nested anchors are invalid and browsers close the outer one early, which
   would silently kill the click target for everything below it. */
.kort { display: flex; flex-direction: column; }
.kort > a { flex: 1 1 auto; }
.kategorimerke {
  align-self: start; margin: 0 12px 12px;
  padding: 3px 10px; border-radius: 999px;
  background: var(--kant); color: var(--dempet);
  font-size: 12px; text-decoration: none;
}
.kategorimerke:hover { background: var(--aksent-lys); color: var(--aksent); }
