/* Middagsbladet — poster-style cookbook. Brand: deep green + tomato orange on cream.
   Colours are lifted from the logo (#074c36 / #e5532f). Light and dark. */

/* ---------------------------------------------------------------- fonts */
/* Self-hosted so the site keeps its zero-third-party, zero-dependency habit. */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fraunces.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: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(/assets/fraunces-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: 'Nunito';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(/assets/nunito.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: 'Nunito';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url(/assets/nunito-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;
}

/* ---------------------------------------------------------------- tokens */

:root {
  --green: #074c36;
  --green-deep: #053527;
  --green-soft: #e2ede6;
  --orange: #e5532f;
  --orange-deep: #c33f1e;
  --orange-soft: #fce8de;

  --paper: #fbf6ec;
  --surface: #fffdf8;
  --ink: #241d17;
  --muted: #766a5c;
  --line: #e7dcc9;
  --head: var(--green);
  --on-dark: #fdf6ea;

  --shadow: 0 1px 2px rgb(36 29 23 / .06), 0 12px 28px -18px rgb(36 29 23 / .35);
  --shadow-lift: 0 2px 6px rgb(36 29 23 / .08), 0 26px 50px -24px rgb(36 29 23 / .45);

  --radius: 18px;
  --display: 'Fraunces', ui-serif, "Iowan Old Style", Georgia, serif;
  --sans: 'Nunito', system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --wrap: 1240px;
  --gap: 3px; /* the whole point of the tile wall: almost no gutter */
}

@media (prefers-color-scheme: dark) {
  :root {
    --green: #2f8b66;
    --green-deep: #0b1f18;
    --green-soft: #12291f;
    --orange: #ff7a50;
    --orange-deep: #ff9573;
    --orange-soft: #2c1810;

    --paper: #10130f;
    --surface: #191d18;
    --ink: #f2e9db;
    --muted: #a99c8b;
    --line: #2b3129;
    --head: #f6ecdd;

    --shadow: 0 1px 2px rgb(0 0 0 / .5), 0 12px 28px -18px rgb(0 0 0 / .8);
    --shadow-lift: 0 2px 6px rgb(0 0 0 / .55), 0 26px 50px -24px rgb(0 0 0 / .9);
  }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 1.0625rem;
  line-height: 1.65;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-variation-settings: 'SOFT' 60, 'WONK' 1, 'opsz' 100;
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--head);
  text-wrap: balance;
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--orange); color: #fff; padding: .75rem 1rem; border-radius: 0 0 10px 0;
}
.skip:focus { left: 0; }

:focus-visible { outline: 3px solid var(--orange); outline-offset: 2px; border-radius: 6px; }

/* A candy stripe across the very top — sets the tone before anything loads. */
.ribbon {
  height: 6px;
  background: repeating-linear-gradient(
    90deg,
    #074c36 0 26px, #e5532f 26px 52px, #f2a33c 52px 78px
  );
}

/* ---------------------------------------------------------------- header */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 90%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1.5px solid var(--line);
}

.bar {
  max-width: var(--wrap); margin: 0 auto;
  padding: .55rem clamp(.85rem, 3vw, 2rem);
  display: flex; align-items: center; gap: clamp(.6rem, 2.5vw, 1.75rem);
}

/* Header runs the lockup horizontally — spoon beside wordmark — so the
   wordmark stays big without making the sticky bar tall. */
.brand {
  display: flex; align-items: center; gap: .55rem;
  flex: 0 0 auto; line-height: 0; text-decoration: none;
}
.brand-mark {
  height: clamp(26px, 3.4vw, 34px); width: auto;
  transform-origin: 70% 60%;
  transition: transform .3s cubic-bezier(.34, 1.56, .64, 1);
}
.brand-word { height: clamp(21px, 2.7vw, 27px); width: auto; }
.brand:hover .brand-mark { transform: rotate(-14deg) scale(1.06); }

@media (max-width: 400px) { .brand-mark { display: none; } }

/* Vinjetten: kategorins namn intill loggan, skilt från den med ett orange
   streck — tidningens sektionsnamn i huvudet i stället för ett rubrikblock som
   trycker ner ettan. Sätt i samma serif som rubrikerna, för den ÄR sidans
   rubrik; att den står i huvudet gör den inte till en meny. */
.brand-section {
  display: flex; align-items: center; gap: clamp(.5rem, 1.6vw, .8rem);
  flex: 0 1 auto; min-width: 0;
  font-family: var(--display); font-weight: 800;
  font-variation-settings: 'SOFT' 40, 'WONK' 0, 'opsz' 72;
  font-size: clamp(1.05rem, 2.4vw, 1.5rem);
  line-height: 1; letter-spacing: -.01em;
  color: var(--head); white-space: nowrap;
}
.brand-section::before {
  content: ""; flex: 0 0 auto; width: 2px; height: 1.35em;
  border-radius: 2px; background: var(--orange);
}
/* Nere vid telefonbredd får menyn gå före: hellre ett huvud på två rader än ett
   som spänner isär sig. Vinjetten står kvar — det är den som säger var man är. */
@media (max-width: 560px) {
  .brand-section { font-size: 1rem; gap: .45rem; }
  .brand-section::before { height: 1.2em; }
}

.foot-logo { display: block; line-height: 0; }
.foot-logo img { height: clamp(70px, 11vw, 96px); width: auto; }

.nav { display: flex; gap: clamp(.5rem, 2vw, 1.1rem); margin-left: auto; }
.nav a {
  text-decoration: none; font-size: .95rem; font-weight: 800; color: var(--ink);
  padding: .35rem .6rem; border-radius: 999px;
  transition: color .15s, background .15s;
}
.nav a:hover { color: #fff; background: var(--orange); }
@media (prefers-color-scheme: dark) { .nav a:hover { color: #1a0d07; } }

.search { display: flex; align-items: center; position: relative; }
.search input {
  font: inherit; font-size: .95rem; font-weight: 600;
  background: var(--surface); color: var(--ink);
  border: 1.5px solid var(--line); border-radius: 999px;
  padding: .48rem 2.4rem .48rem 1rem; width: clamp(7.5rem, 17vw, 14rem);
  transition: border-color .15s, box-shadow .15s;
}
.search input::placeholder { color: var(--muted); font-weight: 600; }
.search input:focus {
  border-color: var(--orange); box-shadow: 0 0 0 4px var(--orange-soft); outline: none;
}
.search button {
  position: absolute; right: .28rem; background: none; border: 0; cursor: pointer;
  padding: .35rem; color: var(--muted); display: grid; place-items: center;
}
.search button svg {
  width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round;
}
.search button:hover { color: var(--orange); }

@media (max-width: 760px) {
  .bar { flex-wrap: wrap; row-gap: .5rem; }
  .nav { margin-left: auto; order: 2; }
  .search { order: 3; flex: 1 1 100%; }
  .search input { width: 100%; }
}

/* ------------------------------------------------------------- kickers */

.kicker {
  margin: 0; font-size: .78rem; font-weight: 800; letter-spacing: .16em;
  text-transform: uppercase; color: var(--orange);
  display: flex; align-items: center; gap: .55rem;
}
.kicker::after {
  content: ""; flex: 0 0 2.2rem; height: 3px; border-radius: 3px;
  background: currentColor; opacity: .55;
}
.kicker.center { justify-content: center; }
.kicker.center::before {
  content: ""; flex: 0 0 2.2rem; height: 3px; border-radius: 3px;
  background: currentColor; opacity: .55;
}

.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--orange); color: #fff;
  padding: .8rem 1.6rem; border-radius: 999px;
  font-weight: 800; font-size: 1rem; text-decoration: none;
  box-shadow: 0 6px 0 -1px var(--orange-deep);
  transition: transform .16s, box-shadow .16s, background .16s;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 8px 0 -1px var(--orange-deep); }
.btn:active { transform: translateY(2px); box-shadow: 0 3px 0 -1px var(--orange-deep); }

/* ---------------------------------------------------------------- hero */

.hero {
  display: grid;
  border-bottom: 1.5px solid var(--line);
  background: var(--surface);
}

.hero-media {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--green-soft);
}
.hero-img { width: 100%; height: 100%; object-fit: cover; }
.hero-media:hover .hero-img { transform: scale(1.03); }
.hero-img { transition: transform .6s ease; }

/* Rotated sticker over the photo — the “fun” cue that a blog card never has. */
.sticker {
  position: absolute; top: clamp(.75rem, 2.5vw, 1.6rem); left: clamp(.75rem, 2.5vw, 1.6rem);
  background: var(--orange); color: #fff;
  font-weight: 800; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  padding: .45rem .9rem; border-radius: 999px; transform: rotate(-4deg);
  box-shadow: 0 6px 18px -6px rgb(0 0 0 / .5);
}

.hero-text {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1rem;
  padding: clamp(1.75rem, 5vw, 4rem) clamp(1.15rem, 5vw, 4rem);
  /* faint dot texture, so the panel does not read as an empty content box */
  background-image: radial-gradient(var(--line) .9px, transparent 1px);
  background-size: 18px 18px;
}
.hero-title {
  font-size: clamp(2.3rem, 6vw, 4.4rem);
  font-variation-settings: 'SOFT' 80, 'WONK' 1, 'opsz' 144;
  margin: 0;
}
.hero-title a { text-decoration: none; }
.hero-title a:hover { color: var(--orange); }
.hero-intro {
  margin: 0; max-width: 40ch; color: var(--muted);
  font-size: clamp(1rem, 1.6vw, 1.18rem); text-wrap: pretty;
}

@media (min-width: 900px) {
  .hero { grid-template-columns: 1.05fr 1fr; align-items: stretch; }
  .hero-media { grid-column: 2; grid-row: 1; aspect-ratio: auto; min-height: 32rem; }
  .hero-text { grid-column: 1; grid-row: 1; justify-content: center; }
}

/* ------------------------------------------------------------- sections */

.section {
  max-width: var(--wrap); margin: 0 auto;
  padding: clamp(2.25rem, 5vw, 4rem) clamp(1rem, 4vw, 2rem);
}
.section.narrow { max-width: 46rem; }
.section.bleed { max-width: none; padding-left: 0; padding-right: 0; }

.section-head {
  display: flex; flex-direction: column; gap: .55rem; align-items: center;
  text-align: center; margin-bottom: clamp(1.25rem, 3vw, 2.25rem);
  padding: 0 clamp(1rem, 4vw, 2rem);
}
.section-head h1, .section-head h2 {
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  font-variation-settings: 'SOFT' 80, 'WONK' 1, 'opsz' 144;
}
.section-sub { margin: 0; color: var(--muted); font-size: 1rem; max-width: 48ch; }

/* ----------------------------------------------------------- tile wall */

.wall {
  display: grid;
  gap: var(--gap);
  grid-auto-flow: dense;
  grid-template-columns: repeat(2, 1fr); /* phones always get a two-up mosaic */
  /* Shows through the 3px gutters, and fills the empty cells of a short last
     row — so it has to be the page colour, not a darker rule colour. */
  background: var(--paper);
  border-block: 1.5px solid var(--line);
}
@media (min-width: 560px) {
  .wall { grid-template-columns: repeat(auto-fill, minmax(min(33.333%, 260px), 1fr)); }
}

.tile {
  position: relative; overflow: hidden;
  aspect-ratio: 1 / 1; background: var(--green-deep);
  isolation: isolate;
}
/* Every eighth tile goes wide, so the wall reads as a mosaic and not a table. */
@media (min-width: 760px) {
  .tile:nth-child(8n + 3) { grid-column: span 2; aspect-ratio: 2 / 1; }
}

.tile-link {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  justify-content: flex-end; text-decoration: none; color: var(--on-dark);
  padding: clamp(.8rem, 1.8vw, 1.35rem);
}
.tile-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  z-index: -2; transition: transform .55s cubic-bezier(.2, .7, .3, 1), filter .35s;
}
.tile-link::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top,
    rgb(5 20 14 / .92) 0%, rgb(5 20 14 / .62) 34%, rgb(5 20 14 / .12) 66%, rgb(5 20 14 / 0) 100%);
  transition: opacity .3s;
}
.tile:hover .tile-img { transform: scale(1.07); }
.tile:hover .tile-link::before { opacity: .88; }

.tile-title {
  color: var(--on-dark);
  font-size: clamp(1.02rem, 1.55vw, 1.35rem);
  font-variation-settings: 'SOFT' 90, 'WONK' 1, 'opsz' 60;
  line-height: 1.15;
  text-shadow: 0 2px 14px rgb(0 0 0 / .45);
}
.tile:nth-child(8n + 3) .tile-title { font-size: clamp(1.1rem, 2.1vw, 1.8rem); }

.tile-note {
  margin: .35rem 0 0; font-size: .78rem; font-weight: 800;
  letter-spacing: .1em; text-transform: uppercase;
  color: rgb(253 246 234 / .74);
  display: flex; align-items: center; gap: .4rem;
}
.tile-note::before {
  content: ""; width: .4rem; height: .4rem; border-radius: 50%; background: var(--orange);
}
/* Orange bar wipes in along the bottom edge on hover. */
.tile-link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 5px;
  background: var(--orange); transform: scaleX(0); transform-origin: left;
  transition: transform .3s ease;
}
.tile:hover .tile-link::after { transform: scaleX(1); }

.img-fallback {
  position: absolute; inset: 0; z-index: -2;
  background: linear-gradient(135deg, var(--green) 0%, var(--green-deep) 55%, var(--orange-deep) 100%);
}

.empty { color: var(--muted); text-align: center; padding: 2rem 1rem; }
.empty a:not(.btn) { color: var(--orange); font-weight: 800; }

/* --------------------------------------------------------------- pager */

.pager {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  flex-wrap: wrap; margin: clamp(1.75rem, 4vw, 2.75rem) auto 0;
  padding: 0 clamp(1rem, 4vw, 2rem);
}
.page-link {
  text-decoration: none; font-weight: 800; color: var(--green);
  padding: .6rem 1.25rem; border: 2px solid var(--green); border-radius: 999px;
  background: transparent; transition: background .15s, color .15s, transform .15s;
}
.page-link:hover { background: var(--green); color: var(--on-dark); transform: translateY(-2px); }

/* -------------------------------------------------------------- recipe */

.recipe-hero { position: relative; background: var(--green-deep); }
.recipe-hero-img { width: 100%; aspect-ratio: 1 / 1; object-fit: cover; max-height: 76vh; }
.recipe-hero-scrim {
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgb(5 20 14 / .93) 0%, rgb(5 20 14 / .55) 38%, rgb(5 20 14 / .08) 72%);
}
.recipe-hero-text {
  position: absolute; inset-inline: 0; bottom: 0; color: var(--on-dark);
  max-width: var(--wrap); margin: 0 auto;
  padding: clamp(1.4rem, 4vw, 3.25rem) clamp(1rem, 4vw, 2rem);
  display: flex; flex-direction: column; gap: .7rem; align-items: flex-start;
}
.recipe-hero-text h1 {
  font-size: clamp(2rem, 5.6vw, 4rem); color: var(--on-dark);
  font-variation-settings: 'SOFT' 90, 'WONK' 1, 'opsz' 144;
  text-shadow: 0 2px 26px rgb(0 0 0 / .5);
}
.recipe-hero-text .kicker { color: #ffc9ab; }

@media (min-width: 820px) {
  .recipe-hero-img { aspect-ratio: 16 / 9; }
}

.lede {
  max-width: 44rem; margin: clamp(1.6rem, 4vw, 2.6rem) auto 0;
  padding: 0 clamp(1rem, 4vw, 2rem);
  font-family: var(--display);
  font-variation-settings: 'SOFT' 60, 'WONK' 0, 'opsz' 40;
  font-size: clamp(1.12rem, 2.2vw, 1.38rem); line-height: 1.55;
  color: var(--ink); text-wrap: pretty;
}

.recipe-cols {
  max-width: var(--wrap); margin: 0 auto;
  padding: clamp(1.75rem, 4vw, 3rem) clamp(1rem, 4vw, 2rem) clamp(2rem, 5vw, 4rem);
  display: grid; gap: clamp(1.5rem, 3.5vw, 3rem);
  align-items: start;
}

@media (min-width: 940px) {
  .recipe-cols { grid-template-columns: minmax(18rem, 22rem) 1fr; }
  .ingredients { position: sticky; top: 6rem; }
}

.recipe-cols h2 {
  font-size: 1.6rem; margin-bottom: 1rem;
  font-variation-settings: 'SOFT' 90, 'WONK' 1, 'opsz' 72;
}

/* ---- ingredients */

.ingredients {
  background: var(--surface); border: 2px solid var(--green);
  border-radius: var(--radius); padding: clamp(1.15rem, 3vw, 1.7rem);
  box-shadow: 6px 6px 0 -1px var(--green-soft);
}
.ing-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.ing { border-bottom: 1px dashed var(--line); }
.ing:last-child { border-bottom: 0; }
.ing label {
  display: flex; align-items: flex-start; gap: .8rem; cursor: pointer;
  padding: .65rem .15rem; /* generous tap target for cooking with messy hands */
  font-weight: 600; transition: color .15s;
}
.ing-check { position: absolute; opacity: 0; width: 0; height: 0; }
.ing label::before {
  content: ""; flex: 0 0 auto; width: 1.35rem; height: 1.35rem; margin-top: .18rem;
  border: 2px solid var(--line); border-radius: 7px; background: var(--paper);
  transition: background .15s, border-color .15s;
}
.ing-check:checked + label {
  color: var(--muted); text-decoration: line-through; text-decoration-color: var(--orange);
}
.ing-check:checked + label::before {
  background: var(--orange) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center / 0.95rem no-repeat;
  border-color: var(--orange);
}
.ing-check:focus-visible + label::before { outline: 3px solid var(--orange); outline-offset: 2px; }

.reset-ings {
  margin-top: 1rem; font: inherit; font-size: .85rem; font-weight: 800;
  background: none; border: 2px solid var(--line); border-radius: 999px;
  padding: .45rem 1.1rem; color: var(--muted); cursor: pointer;
}
.reset-ings:hover { border-color: var(--orange); color: var(--orange); }

/* ---- steps */

.steps { list-style: none; margin: 0; padding: 0; }
.step {
  display: flex; gap: clamp(.9rem, 2vw, 1.4rem);
  padding: 1.05rem 0; border-bottom: 1px dashed var(--line);
}
.step:last-child { border-bottom: 0; }
.step p { margin: 0; font-size: 1.075rem; line-height: 1.7; text-wrap: pretty; }
.step-n {
  flex: 0 0 auto; width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: var(--orange); color: #fff;
  font-family: var(--display); font-size: 1.2rem; font-weight: 800;
  font-variation-settings: 'SOFT' 100, 'WONK' 1, 'opsz' 40;
  display: grid; place-items: center;
}
/* Texten och stegets bilder ligger i samma spalt, till höger om siffran.
   min-width: 0 så en bred bild inte spränger flexraden. */
.step-body { flex: 1 1 auto; min-width: 0; }

/* ---- processbilder */

.step-figure { margin: 1rem 0 .35rem; }
.step-figure img {
  display: block; width: 100%; height: auto;
  border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--green-soft); /* syns medan bilden laddar */
}
.step-figure figcaption {
  margin-top: .55rem; font-size: .92rem; line-height: 1.5;
  color: var(--muted); text-wrap: pretty;
}

/* Bilderna sist på sidan: en spalt, samma läsmått som prosan. */
.recipe-gallery {
  max-width: 44rem; margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2rem) clamp(2.5rem, 6vw, 4rem);
  display: flex; flex-direction: column; gap: clamp(1.4rem, 3vw, 2.2rem);
}
.recipe-gallery .step-figure { margin: 0; }
/* Prosainlägg har redan en botteninsats i .prose — dubbla den inte. */
.prose + .recipe-gallery { padding-top: 0; }

.related { border-top: 0; }

/* --------------------------------------------------------------- prose */

.prose, .page {
  max-width: 44rem; margin: 0 auto;
  padding: clamp(1.6rem, 4vw, 2.75rem) clamp(1rem, 4vw, 2rem) clamp(2.5rem, 6vw, 4rem);
}
/* A page already provides the column, so its prose must not inset again. */
.page .prose { max-width: none; padding: 0; }
.page h1 {
  font-size: clamp(2rem, 5vw, 3rem); margin: .5rem 0 1.25rem;
  font-variation-settings: 'SOFT' 80, 'WONK' 1, 'opsz' 144;
}

/* ---- fristående sida i två spalter (se simplePage() i app/render.js)

   Vänsterspalten behåller prosans läsmått — 44rem är valt för att raderna ska
   gå att läsa, och en bredare sida får inte göra dem längre. Sidan blir alltså
   bredare genom att marginalspalten LÄGGS TILL, inte genom att texten sträcks.
   Under 900px faller allt tillbaka i en spalt och marginalen hamnar sist. */
.page-split { max-width: 72rem; }
.page-cols { display: grid; gap: clamp(1.6rem, 4vw, 3rem); align-items: start; }
/* Marginalspalten har ett TAK i rem och inte bara en andel: bilden är en
   inskannad förstasida på 274 pixlar, och en spalt som växer med fönstret hade
   skalat upp den tills pappret blev grötigt. */
@media (min-width: 900px) {
  .page-cols { grid-template-columns: minmax(0, 1.6fr) minmax(14rem, 20rem); }
}
.page-cols .prose { max-width: 44rem; }

.page-aside-inner {
  display: flex; flex-direction: column; gap: clamp(1.2rem, 3vw, 1.8rem);
}
.page-aside figure { margin: 0; }
/* `width: auto` och inte `100%`: i en spalt ligger bilden i sitt eget mått. En
   inskannad förstasida på 274 pixlar utsträckt över en hel telefonskärm är
   gröt, och att spara plats genom att sudda ut bilden är ingen besparing. */
.page-aside img {
  width: auto; max-width: 100%; height: auto;
  border-radius: var(--radius); box-shadow: var(--shadow);
  background: var(--green-soft);
}

/**
 * Bilden slutar där texten slutar.
 *
 * Marginalspalten lyfts ur flödet — `position: absolute` inuti en `relative`
 * spalt — så att RADENS höjd bestäms av textspalten ensam. Utan det blir raden
 * så hög som bilden själv vill vara, och den kan aldrig krympa till textens
 * höjd: bilden skulle definiera det mått den sedan skulle rätta sig efter.
 *
 * Bilden får `height: 100%` och `width: auto` — alltså INTE `object-fit`. Med
 * object-fit hade elementets ruta fortsatt vara full spaltbredd och bilden
 * legat inklämd i den med en tom remsa bredvid, och remsan hade burit
 * bakgrunden, hörnradien och skuggan som hör till pappret. Nu följer bredden av
 * höjden genom bildens egna proportioner, så rutan är bilden. Beskuren blir den
 * aldrig: en förstasida från 1892 får inte klippas för layoutens skull.
 *
 * Blir texten längre än bilden kan fylla stannar bilden vid sin naturliga
 * bredd i stället för att skalas upp till gröt, och slutar då före texten. Det
 * är den ärliga gränsen: ett original på 274 pixlar kan inte bli större.
 *
 * `min-height` är golvet för en riktigt kort sida, så bilden inte pressas till
 * en strimma.
 */
@media (min-width: 900px) {
  .page-aside { position: relative; align-self: stretch; min-height: 18rem; }
  .page-aside-inner { position: absolute; inset: 0; }
  .page-aside figure {
    flex: 1 1 auto; min-height: 0;
    display: flex; flex-direction: column; align-items: flex-start;
  }
  .page-aside img { flex: 1 1 auto; min-height: 0; height: 100%; width: auto; max-width: 100%; }
}
.page-aside figcaption {
  margin-top: .6rem; font-size: .88rem; line-height: 1.5;
  color: var(--muted); text-wrap: pretty;
}

/* Utgivarrutan: tidningens redaktionsruta. Den ska gå att hitta med fingret på
   en gång — det är den ansvarige utgivaren en läsare letar efter — men den är
   inte sidans huvudtext, så den är satt mindre och i sajtens sans. */
.colophon {
  margin-top: clamp(.4rem, 2vw, 1rem);
  max-width: 44rem;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-left: 4px solid var(--orange);
  border-radius: calc(var(--radius) - 6px);
  padding: clamp(.9rem, 2.5vw, 1.2rem) clamp(1rem, 2.5vw, 1.3rem);
}
.colophon p { margin: 0; font-size: .95rem; line-height: 1.6; text-wrap: pretty; }
.colophon strong { font-weight: 700; }
.colophon a { color: var(--orange); font-weight: 700; text-underline-offset: 3px; }
.prose p { margin: 0 0 1.15rem; text-wrap: pretty; }
.prose h2, .prose h3 { margin: 2.2rem 0 .8rem; font-size: 1.6rem; }
.prose ul, .prose ol { padding-left: 1.3rem; margin: 0 0 1.15rem; }
.prose li { margin-bottom: .45rem; }
.prose img { border-radius: var(--radius); margin: 1.6rem 0; box-shadow: var(--shadow); }
.prose a { color: var(--orange); font-weight: 700; text-underline-offset: 3px; }
.prose blockquote {
  margin: 1.6rem 0; padding: .35rem 0 .35rem 1.2rem;
  border-left: 4px solid var(--orange); color: var(--muted);
  font-family: var(--display); font-size: 1.2rem;
}

/* --------------------------------------------------------- search page */

.search.big { max-width: 36rem; margin: 0 auto 2.5rem; gap: .6rem; }
.search.big input {
  width: 100%; padding: .95rem 1.3rem; border-radius: 999px; font-size: 1.05rem;
  border-width: 2px;
}
.search.big button {
  position: static; background: var(--orange); color: #fff; border-radius: 999px;
  padding: .95rem 1.7rem; font: inherit; font-weight: 800; font-size: 1rem;
  box-shadow: 0 5px 0 -1px var(--orange-deep);
}
.search.big button:hover { background: var(--orange-deep); color: #fff; }

/* -------------------------------------------------------------- footer */

.site-footer { background: var(--green-deep); color: var(--on-dark); margin-top: auto; }
.foot-inner {
  max-width: var(--wrap); margin: 0 auto;
  padding: clamp(2.25rem, 5vw, 3.5rem) clamp(1rem, 4vw, 2rem);
  display: grid; gap: 1.4rem; justify-items: center; text-align: center;
}
.foot-tag {
  margin: 0; font-family: var(--display); font-size: 1.15rem;
  font-variation-settings: 'SOFT' 80, 'WONK' 1, 'opsz' 40;
  color: rgb(253 246 234 / .85);
}
.foot-inner nav { display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem 1.4rem; }
.foot-inner nav a {
  color: rgb(253 246 234 / .8); text-decoration: none; font-weight: 700; font-size: .95rem;
}
.foot-inner nav a:hover { color: var(--orange); }
.foot-note { margin: 0; color: rgb(253 246 234 / .5); font-size: .82rem; }

/* ------------------------------------------------------------ niceties */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .tile:hover .tile-img, .brand:hover img, .hero-media:hover .hero-img { transform: none; }
}

/* --------------------------------------------------------------- källor */

/**
 * Källistan under en nyhetsartikel.
 *
 * Samma läsmått som prosan, tydligt avskild men underordnad: den ska gå att
 * kontrollera, inte konkurrera med texten. Bara källor märkta 'outlet' hamnar
 * här — se sourceList() i app/render.js.
 */
.sources {
  max-width: 44rem;
  margin: 0 auto;
  padding: 0 clamp(1rem, 4vw, 2rem) clamp(2.5rem, 6vw, 4rem);
}
.sources h2 {
  font-family: var(--sans);
  font-size: .82rem; font-weight: 800;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 .7rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--line);
}
.sources ul { list-style: none; padding: 0; margin: 0; }
.sources li {
  margin: 0 0 .5rem;
  font-size: .95rem;
  color: var(--muted);
  text-wrap: pretty;
}
.sources a { color: var(--orange); font-weight: 700; text-underline-offset: 3px; }

/* Prosan och galleriet bär redan sin understa luft; annars blir den dubbel. */
.prose + .sources,
.recipe-gallery + .sources { padding-top: 0; }

@media print {
  .ribbon, .site-header, .site-footer, .related, .pager, .reset-ings, .sticker { display: none; }
  /* Källorna följer med i utskriften — de hör till artikeln. */
  .sources a { color: #000; }
  .recipe-hero { max-height: 8cm; overflow: hidden; }
  .recipe-cols { display: block; }
  .ingredients { box-shadow: none; }
  /* Stegbilderna får plats, men små: receptet ska rymmas på ett papper. */
  .step-figure img { max-height: 6cm; width: auto; box-shadow: none; }
  .recipe-gallery { display: none; }
  body { background: #fff; color: #000; }
}

/* ------------------------------------------------------------ tidningssida */

/**
 * Kategorisidan för det som är text — nyheter, humor — byggd som en tidnings
 * förstasida: en etta överst, därunder rader av allt mindre artiklar och sist
 * en spalt notiser.
 *
 * Bildväggen är byggd för recept: kvadrater, foto över hela ytan, titeln
 * ovanpå. Man väljer med ögonen och behöver inget mer. En artikel väljer man
 * med rubriken och ingressen, och en tidning visar dessutom med FORMATET vad
 * som är viktigast. Storlekarna här är därför en trappa och inte ett upprepat
 * mönster: se magazine() i app/render.js.
 *
 * TRE SAKER SKILJER DEN TRYCKTA SIDAN FRÅN KORTRUTNÄTET, och alla tre finns
 * här för att den förra versionen saknade dem och därför läste sig som en
 * blogg hur väl den än var proportionerad:
 *
 * 1. Rutnätet ritas med LINJER, inte med luft. Ett kort som svävar i en
 *    mellanrumsyta är ett kort; en spalt med en hårfin linje i rännan bredvid
 *    sig är en spalt. Linjen ritas mitt i rännan av spalten till höger om den —
 *    se .mag-row för varför den inte får vara en `border-left` på cellen.
 *    Raderna är egna behållare (.mag-row) för att `+ .mag-card` då aldrig kan
 *    sätta en linje vid en radbörjan; det gick inte att göra säkert när allt låg
 *    i ett sexspaltigt rutnät och cellerna spände olika brett.
 * 2. Fotona är RÄTA. Rundade hörn är webbens kort, inte tryckets bilder. Av
 *    samma skäl finns ingen zoom vid hovring: en tidning rör sig inte.
 * 3. Ingen etikett och ingen knapp. Se magLead() i app/render.js.
 *
 * Typografin är tidningens: rubriker i Fraunces tätt satta, fet ingång på
 * ingressen, hårfina linjer i stället för kort med skuggor.
 */

/* Vinjetten står i huvudet (.brand-section), inte här: sidan börjar direkt med
   ettan. Luften ovanför den kommer från .section — mindre än den var, med flit.

   `--rule` är HALVA rännan mellan två spalter, och den bor här för att både
   raderna och notisspalten mäter sig mot den — se .mag-row. Den behöver ingen
   brytpunkt: under 620 px är raderna enspaltiga och under 900 px är notiserna
   det, så en ränna utan grannar att skilja åt kostar ingenting. */
.section.paper {
  --rule: clamp(1rem, 2.2vw, 1.75rem);
  max-width: 74rem;
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
}

/* ------- gemensamt för etta, kort och notiser */

.mag-lead a, .mag-title a, .mag-note-title a { color: var(--head); text-decoration: none; }
.mag-lead a:hover, .mag-title a:hover, .mag-note-title a:hover { color: var(--orange); }
/* Hela ytan blir klickbar härifrån, så bilden slipper vara en andra länk till
   samma artikel — en skärmläsare hade annars läst upp den två gånger. */
.mag-lead-title a::after,
.mag-title a::after,
.mag-note-title a::after { content: ""; position: absolute; inset: 0; }

.mag-img, .mag-lead-img, .mag-note-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
}

/* Ingången i fet, tidningens gamla knep. Se deck() i app/render.js. */
.mag-lede { color: var(--head); font-weight: 800; }

/* ------- ettan */

.mag-lead {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1rem, 2.5vw, 1.8rem);
  padding-bottom: clamp(1.4rem, 3vw, 2.2rem);
  border-bottom: 3px solid var(--ink);
}
/*
 * `minmax(0, …)` och inte bara `1.5fr 1fr`: ett fr-spår är i själva verket
 * `minmax(auto, 1fr)` och kan aldrig bli smalare än sitt min-content. Textspaltens
 * min-content är det LÄNGSTA ORDET i rubriken, och svenskan har gott om
 * "Jämställdhetsmyndigheten" — 763 px satt i 3,5 rem. Den lade beslag på 70 % av
 * raden och tryckte ihop fotot till 30 % i stället för utlovade 61 %, olika
 * mycket för varje artikel beroende på dess längsta ord. Mätt på /humor/.
 */
@media (min-width: 820px) {
  .mag-lead { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: center; }
}

.mag-lead-media {
  position: relative; overflow: hidden;
  aspect-ratio: 16 / 10;
  background: var(--green-deep);
}

/*
 * Grad och spaltbredd är satta MOT VARANDRA så att avstavningen blir
 * skyddsnätet och inte formgivningen. Uppmätt i Fraunges vid 2,6 rem: det
 * längsta ordet någon etta har haft, "Jämställdhetsmyndigheten", är 467 px och
 * "kulturdepartementet" 364 px. Textspalten är 474 px vid 1,3fr — båda ryms
 * alltså hela, och det är därför spalten inte fick bli smalare.
 *
 * `text-wrap: pretty` och inte `balance`: balance jämnar ut radlängderna, och
 * när en rubrik ändå måste avstavas en gång betalar den utjämningen genom att
 * avstava EN GÅNG TILL. Det var så "kulturdepartementet" bröts mitt i ordet
 * trots att det fick plats på en rad.
 *
 * `hyphens` behövs ändå: mellan 820 och ~1200 px krymper spalten fortare än
 * graden, och utan avstavning spräcker ett långt sammansatt svenskt ord spalten
 * med overflow i stället. Sidan är `lang="sv"`, så brytningen följer svenska
 * ordled; `overflow-wrap` är golvet för den vars webbläsare saknar ordlistan.
 */
.mag-lead-title {
  font-family: var(--display);
  font-variation-settings: 'SOFT' 40, 'WONK' 1, 'opsz' 144;
  font-size: clamp(1.8rem, 3.6vw, 2.6rem);
  line-height: 1.03;
  letter-spacing: -.025em;
  margin: 0 0 .7rem;
  text-wrap: pretty;
  hyphens: auto;
  overflow-wrap: break-word;
}
.mag-lead-intro {
  margin: 0;
  font-size: clamp(1rem, 1.5vw, 1.12rem);
  line-height: 1.5;
  color: var(--muted);
  text-wrap: pretty;
}

/* ------- raderna */

/*
 * Rännan är en RIKTIG `column-gap` och hårlinjen ritas mitt i den med ett
 * pseudoelement, i stället för att ligga som `border-left` på cellen med luften
 * betald ur cellens padding.
 *
 * Skillnaden är inte kosmetisk. Med padding-varianten måste ytterkanterna
 * nollas för att spalterna ska gå jäms med ettan — `:first-child` tappar sin
 * vänsterpadding, `:last-child` sin högra — och då blir MITTENCELLEN i en
 * trerad en ränna smalare än sina grannar. En smalare cell ger en lägre
 * `aspect-ratio`-ruta, alltså ett kortare foto, alltså en rubrik som börjar
 * högre upp än de andra två. Det syntes direkt på /humor/.
 *
 * Med en äkta ränna är alla spår exakt lika breda, ytterkanterna ligger kvar
 * mot ettans kanter, och linjen hamnar mitt emellan spalterna i stället för
 * tätt intill texten. Att den ritas som `::before` och inte som `border-left`
 * är också det som låter den gå hela radens höjd: cellen sträcks av rutnätet,
 * så `top: 0; bottom: 0` möter den vågräta linjen ovanför.
 */
.mag-row {
  display: grid; grid-template-columns: 1fr;
  row-gap: clamp(1.5rem, 3vw, 2rem);
  column-gap: calc(var(--rule) * 2);
}
.mag-row + .mag-row,
.mag-row + .mag-notes { border-top: 1px solid var(--line); }

/* Linjen mitt i rännan, ritad av spalten till höger om den. Den är avstängd
   som grundläge och tänds först vid den brytpunkt där spalten faktiskt HAR en
   granne till vänster — enspaltigt vore den ett lodrätt streck ute i marginalen.
   Att den är absolut positionerad är också det som gör att den inte blir ett
   eget rutnäts- eller flexbarn i cellen den ritas av. */
.mag-card + .mag-card::before,
.mag-note:nth-child(2n)::before {
  content: ""; display: none;
  position: absolute; top: 0; bottom: 0; left: calc(var(--rule) * -1);
  border-left: 1px solid var(--line);
}

/* `minmax(0, 1fr)` av samma skäl som i ettan: spåren ska vara lika breda även
   när en rubrik innehåller ett ord som är bredare än sitt spår. Utan det äter
   den cellen av sina grannar och hela poängen med lika breda spalter faller. */
@media (min-width: 620px) {
  .mag-row { row-gap: 0; }
  .mag-row-mid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mag-row-small { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .mag-card + .mag-card::before { display: block; }
}

.mag-card {
  position: relative;
  display: flex; flex-direction: column;
  padding-top: clamp(1.3rem, 2.6vw, 1.9rem);
  padding-bottom: clamp(.4rem, 1vw, .8rem);
}
/* Fyrkantiga foton — se punkt 2 i blocket överst. */
.mag-media {
  position: relative; overflow: hidden;
  margin-bottom: .8rem;
  background: var(--green-deep);
}
.mag-mid .mag-media { aspect-ratio: 3 / 2; }
.mag-small .mag-media { aspect-ratio: 4 / 3; }
.mag-wide .mag-media { aspect-ratio: 21 / 9; }

.mag-title {
  font-family: var(--display);
  font-variation-settings: 'SOFT' 50, 'WONK' 1, 'opsz' 60;
  line-height: 1.08;
  letter-spacing: -.015em;
  margin: 0 0 .45rem;
  text-wrap: balance;
  hyphens: auto;
  overflow-wrap: break-word;
}
.mag-mid .mag-title { font-size: clamp(1.3rem, 2.7vw, 1.85rem); }
.mag-small .mag-title { font-size: clamp(1.05rem, 1.9vw, 1.25rem); }
.mag-wide .mag-title { font-size: clamp(1.5rem, 3.2vw, 2.2rem); }

/*
 * Bara tvåorna har ingress. Treorna är foto och rubrik — se magCard().
 *
 * Tre rader är GRUNDVÄRDET, inte facit. Två artiklar bredvid varandra har olika
 * långa rubriker — en bryts på två rader, en på en — och rutnätet sträcker båda
 * cellerna till radens höjd. Cellen med kort rubrik får då ett tomt fält under
 * sin ingress, ungefär en rubrikrad hög, alltså mer än en och en halv
 * ingressrad. `--intro-lines` finns för att det fältet ska kunna fyllas med
 * text i stället för med luft; app.js mäter och höjer talet per cell.
 *
 * Antalet är en variabel och inte ett tal just därför: utan skript står
 * ingressen kvar på sina tre rader, vilket är precis vad den gjorde förut.
 */
.mag-intro {
  --intro-lines: 3;
  margin: 0;
  font-size: .94rem;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
  /* Klippt vid en hel rad, aldrig mitt i en: raden ska ha en jämn kant, och en
     avhuggen mening är ärligare än en cell som växer förbi sin granne. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: var(--intro-lines);
  line-clamp: var(--intro-lines);
  overflow: hidden;
}
.mag-wide .mag-intro { --intro-lines: 2; }

/* ------- notiserna */

.mag-notes { padding-top: clamp(1.4rem, 2.8vw, 2rem); }

/* Spaltrubriken sitter på en linje, som en sidfotsvinjett i tryck. */
.mag-notes-head {
  font-family: var(--sans);
  font-size: .72rem; font-weight: 800;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 .3rem;
}

.mag-notes-list {
  display: grid; grid-template-columns: 1fr;
  column-gap: calc(var(--rule) * 2);
}
@media (min-width: 900px) {
  .mag-notes-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mag-note:nth-child(2n)::before { display: block; }
}

.mag-note {
  position: relative;
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 1rem;
  padding-block: .8rem;
  border-top: 1px solid var(--line);
}
.mag-note-title {
  font-family: var(--display);
  font-variation-settings: 'SOFT' 50, 'WONK' 1, 'opsz' 40;
  font-size: clamp(1rem, 1.6vw, 1.12rem);
  line-height: 1.18;
  letter-spacing: -.01em;
  margin: 0;
  text-wrap: pretty;
}
.mag-note-media {
  position: relative; overflow: hidden;
  width: 74px; height: 74px;
  background: var(--green-deep);
}

@media print {
  .mag-lead, .mag-card, .mag-note { break-inside: avoid; }
  .mag-lead-media, .mag-media, .mag-note-media { display: none; }
  .mag-row, .mag-notes-list { display: block; }
  /* Enspaltigt på papper: rännans linje har inget att skilja åt. */
  .mag-card + .mag-card::before, .mag-note::before { display: none; }
}


/* Bildtexten under hjältebilden.

   Samma spaltbredd och sidopadding som .lede, inte hela den helbredda bildens
   bredd: en rad som börjar vid skärmkanten läses som ett bildspråk i en annons
   i stället för som en bildtext i en tidning. Sans mot ingressens antikva, och
   --muted, så att den går att läsa utan att tävla med den. Färgen följer
   automatiskt med i mörkt läge — --muted är omdefinierad där. */
.hero-credit {
  max-width: 44rem;
  margin: clamp(0.75rem, 2vw, 1.1rem) auto 0;
  padding: 0 clamp(1rem, 4vw, 2rem);
  font-family: var(--sans);
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--muted);
  text-wrap: pretty;
}
