/* Self-hosted fonts, one per look (web/themes.js `font`; app.js sets --font). Variable fonts, latin subset (covers
   å ä ö), from the @fontsource-variable packages; each family's licence is the SIL Open Font License, kept beside
   the file as OFL.txt. */
@font-face {
  font-family: "Albert Sans";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/albert-sans/albert-sans-latin-wght-normal.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: "Familjen Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/familjen-grotesk/familjen-grotesk-latin-wght-normal.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: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/inter/inter-latin-wght-normal.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: "Schibsted Grotesk";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/schibsted-grotesk/schibsted-grotesk-latin-wght-normal.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;
}

/* Hus för hus: a pale architectural model under a northern sky. The colour tokens, the font and the color-scheme
   below are the default look, Ärg (D28, web/look.js DEFAULT_LOOK), so the first paint is already in it;
   app.js overwrites them from web/themes.js for the other looks (?theme=kalk|blatimme|paper).
   web/test/styles.test.mjs checks that they match. */
:root {
  --bg: #e7ecef;
  --panel: #ffffff;
  --ink: #121a21;
  --muted: #59636b;
  --line: #d3dade;
  --accent: #c2410c;
  --gutter: clamp(16px, 2.4vw, 32px);
  --font: "Schibsted Grotesk";
  color-scheme: light;
  font: 400 14px/1.5 var(--font), "Helvetica Neue", Arial, sans-serif;
}
* { box-sizing: border-box; }
/* Hidden v1.1 controls (feature flags) must stay hidden even where a rule sets their display. */
[hidden] { display: none !important; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink); overflow: hidden; }
button { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

#scene { position: fixed; inset: 0; width: 100%; height: 100%; display: block; }
/* Sky veils keep the masthead and the timeline legible over the model. */
.veil { position: fixed; left: 0; right: 0; pointer-events: none; }
.veil-top { top: 0; height: 150px; background: linear-gradient(var(--veil, var(--bg)) 35%, transparent); }
.veil-bottom { bottom: 0; height: 150px; background: linear-gradient(transparent, var(--veil, var(--bg)) 55%); }

/* Masthead: the name set large and tight, the subtitle under it. */
.masthead { position: fixed; top: calc(env(safe-area-inset-top, 0px) + var(--gutter)); left: var(--gutter);
  display: flex; gap: 14px; align-items: flex-start; pointer-events: none; }
.sibling { position: fixed; right: var(--gutter); top: calc(env(safe-area-inset-top, 0px) + var(--gutter) + 124px);
  color: var(--muted); font-size: 12px; text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 3px; }
h1 { margin: 0; font-size: clamp(34px, 4.4vw, 56px); font-weight: 800; letter-spacing: -0.035em; line-height: .9; }
.kicker { display: block; font-size: 0.36em; font-weight: 600; letter-spacing: 0; color: var(--muted); margin-bottom: 0.18em; }
.dek { margin: 8px 0 0; color: var(--muted); max-width: 26ch; font-size: 14px; line-height: 1.4; }

/* Mode switch: a single bar, the active mode filled black. */
.modes { position: fixed; top: calc(env(safe-area-inset-top, 0px) + var(--gutter)); left: 50%; transform: translateX(-50%);
  display: flex; background: var(--panel); border-radius: 999px; padding: 3px; box-shadow: 0 1px 0 var(--line); }
.modes button { border: 0; background: none; padding: 7px 16px; border-radius: 999px; cursor: pointer; font-weight: 500; }
.modes button[aria-pressed="true"] { background: var(--ink); color: var(--panel); }

/* Top right: the tally, and the buttons under it. A column, so a title on two lines pushes the buttons down. */
.corner { position: fixed; top: calc(env(safe-area-inset-top, 0px) + var(--gutter)); right: var(--gutter);
  display: flex; flex-direction: column; align-items: flex-end; gap: 14px; }
.tally { text-align: right; }
/* The title's line box is tighter than its letters (line-height .85): the descenders of "Today" and "I dag" hang below
   it by up to about a seventh of the size, so a margin keeps them clear of the count line under it, by 3 px or more in
   every look (e2e: the title over the count never touches the count line). */
.tally-year { display: block; font-size: clamp(40px, 5vw, 64px); font-weight: 800; letter-spacing: -0.04em; line-height: .85;
  margin-bottom: .12em; }
/* A period's name is a phrase, not a number: smaller, and on up to two balanced lines. */
.tally-year.named { font-size: clamp(24px, 2.6vw, 34px); letter-spacing: -0.025em; line-height: 1.02; max-width: 12em;
  margin-left: auto; margin-bottom: 4px; text-wrap: balance; }
.tally-count { color: var(--muted); }

/* Context panel: legend, ramp or layer list, always on the left under the masthead. */
.panel { position: fixed; left: var(--gutter); top: calc(env(safe-area-inset-top, 0px) + var(--gutter) + 120px);
  width: min(340px, calc(100vw - 2 * var(--gutter))); max-height: calc(100vh - 300px); overflow-y: auto;
  background: var(--panel); border-radius: 10px; padding: 14px 16px; }
.panel h2 { margin: 0 0 8px; font-size: 13px; font-weight: 700; }
.panel h2.section { margin: 14px 0 4px; color: var(--muted); font-weight: 600; }
.panel h2.section:first-child { margin-top: 0; }
.panel h2.section { display: flex; align-items: center; gap: 7px; scroll-margin-top: 6px; }
.icon { width: 16px; height: 16px; flex: none; }
.layer-title .icon { width: 20px; height: 20px; margin-right: 8px; vertical-align: -3px; }
.jump { display: flex; gap: 4px; margin: 0 0 10px; position: sticky; top: -14px; background: var(--panel); padding: 6px 0; z-index: 1; }
.jump button { width: 34px; height: 34px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  display: grid; place-items: center; cursor: pointer; color: var(--ink); }
.jump button:hover { background: var(--bg); }
.jump .icon { width: 18px; height: 18px; }
/* Under the tally: the north button, the Look button, then About (and the two language letters). */
.buttons { display: flex; align-items: center; gap: 6px; }
.lang { display: flex;
  background: var(--panel); border-radius: 999px; padding: 2px; }
.lang button { border: 0; background: none; padding: 3px 9px; border-radius: 999px; cursor: pointer; font-size: 12px; font-weight: 600; color: var(--muted); }
.lang button[aria-pressed="true"] { background: var(--ink); color: var(--panel); }
.swatches { display: flex; flex-direction: column; }
.swatch { display: grid; grid-template-columns: 12px 1fr auto; gap: 10px; align-items: center; background: none; border: 0;
  text-align: left; padding: 4px 0; cursor: pointer; }
.swatch i { width: 12px; height: 12px; border-radius: 2px; }
.swatch .n { color: var(--muted); font-size: 12px; }
.swatch.unknown { cursor: default; row-gap: 2px; }
/* The "Year unknown" row's switch, "Show" (D30, revised): under the label, a small track in the muted ink that fills
   with the accent when on. On reads "they are on the map now". A button with aria-pressed, like the legend's other
   choices; with a period shown alone it reads off and is aria-disabled, dimmed. Its hint, what the switch does now, is
   the row's last line. The hide-estimates switch (spec §3.3) is the same switch on a row of its own (.est-row below). */
.swatch.unknown .switch, .est-row .switch { grid-column: 2 / -1; justify-self: start; display: inline-flex; align-items: center; gap: 8px;
  min-height: 24px; padding: 0; border: 0; background: none; color: var(--muted); font-size: 12px; text-align: left; cursor: pointer; }
.switch .toggle { position: relative; flex: none; width: 24px; height: 14px; border: 1.5px solid var(--muted); border-radius: 999px; }
.switch .toggle::after { content: ""; position: absolute; top: 2px; left: 2px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted); transition: transform .15s ease; }
.swatch.unknown .switch[aria-pressed="true"], .est-row .switch[aria-pressed="true"] { color: var(--ink); } /* as specific as the base rule above, which sets the muted ink */
.switch[aria-pressed="true"] .toggle { background: var(--accent); border-color: var(--accent); }
.switch[aria-pressed="true"] .toggle::after { background: var(--panel); transform: translateX(10px); }
.switch[aria-disabled="true"] { opacity: .45; cursor: default; }
.swatch.unknown .unknown-hint { grid-column: 2 / -1; color: var(--muted); font-size: 12px; line-height: 1.35; }
.photo-hint, .plaques-hint { display: block; margin: 2px 0 0 38px; color: var(--muted); font-size: 12px; line-height: 1.35; }
/* The hide-estimates row stands apart from "Year unknown": under a hairline, its track at the legend's left edge, under
   the period chips rather than under the "Show" track. On reads "the estimated years are hidden". */
.est-row { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
/* Legend handle. On a desktop it is the panel's header row (sticky, so it stays reachable in a long list) and,
   when folded, the whole panel shrinks to this one pill. The phone sheet below restyles it. */
@media not all and (max-width: 720px) {
  .panel { --handle-h: 34px; padding-top: 0; }
  .sheet-handle { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between;
    width: calc(100% + 32px); height: var(--handle-h); margin: 0 -16px; padding: 0 16px; border: 0; background: var(--panel);
    font: inherit; font-size: 13px; font-weight: 700; color: var(--ink); text-align: left; cursor: pointer; }
  .sheet-handle:focus-visible { outline-offset: -2px; }
  .sheet-handle::after { content: ""; flex: none; width: 7px; height: 7px; margin: 0 2px 0 14px; border: solid var(--muted);
    border-width: 0 2px 2px 0; transform: translateY(2px) rotate(225deg); }
  .jump { top: var(--handle-h); }
  .panel.collapsed { width: auto; padding: 0; overflow: hidden; border-radius: 999px; box-shadow: 0 1px 0 var(--line); }
  .panel.collapsed .sheet-handle { width: auto; margin: 0; padding: 0 14px 0 16px; }
  .panel.collapsed .sheet-handle::after { transform: translateY(-2px) rotate(45deg); }
  .panel.collapsed #panel-body { display: none; }
}
.src { font-size: 12px; color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; }
.layer-intro { margin: 6px 0 10px; line-height: 1.5; }
.filter { width: 100%; font: inherit; padding: 7px 10px; border: 1px solid var(--line); border-radius: 6px; margin-bottom: 6px; background: var(--panel); }
.people .addr { color: var(--ink); opacity: .55; }
.n, .tally, .card dd, .card .y { font-variant-numeric: tabular-nums; }
/* Classic's font (Schibsted Grotesk) has tabular forms of the comma and the full stop as wide as a figure, so a count read
   "77 , 743". In that look the counts, which carry a thousands separator, take proportional figures; the years keep
   tabular ones (e2e: a count's thousands comma is drawn narrow). */
[data-theme="paper"] :is(.n, .tally-count, .card dd) { font-variant-numeric: normal; }
.swatch[aria-pressed="false"] { opacity: .35; }
.ramp { height: 10px; border-radius: 2px; margin: 4px 0 6px; }
.ramp-scale { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; }
.note { color: var(--muted); font-size: 12px; margin: 10px 0 0; }
/* The latin font subsets lack "≈" (W7): the card, the legend's note and the About notice set it in the system font on
   purpose, never a random fallback. */
.approx { font-family: system-ui, -apple-system, "Segoe UI", sans-serif; }

.layers { display: flex; flex-direction: column; gap: 2px; margin: 0 -8px; }
.layer { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; background: none; border: 0; text-align: left;
  padding: 8px; border-radius: 6px; cursor: pointer; }
.layer:hover { background: var(--bg); }
.layer[aria-pressed="true"] { background: var(--ink); color: var(--panel); }
.layer b { font-weight: 700; }
.layer .era, .layer .n { font-size: 12px; opacity: .7; }
.layer .n { grid-row: 1 / 3; grid-column: 2; align-self: center; }
.layer-detail { margin-top: 10px; }
.stories { list-style: none; margin: 0 -8px; padding: 0; }
.story { display: block; width: 100%; text-align: left; background: none; border: 0; border-radius: 6px; padding: 7px 8px; cursor: pointer; }
.story:hover { background: var(--bg); }
.story b { display: block; font-weight: 600; }
.story span { display: block; color: var(--muted); font-size: 12px; line-height: 1.45; margin-top: 2px; }
.back { border: 0; background: none; padding: 0; margin: 0 0 10px; color: var(--muted); cursor: pointer; font-size: 13px; }
.back::before { content: "‹ "; }
.layer-title { font-size: 22px !important; font-weight: 800 !important; letter-spacing: -0.02em; margin: 0 !important; line-height: 1.1; }
.layer-era { margin: 2px 0 0; color: var(--muted); }
.layer-detail p { margin: 0 0 10px; line-height: 1.55; }
.layer-detail a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; font-size: 12px; }
.caveat { color: var(--muted); font-size: 12px; }

/* Building card: a white slip of paper. Follows the pointer on hover; pinned by a click, then it takes clicks.
   Hierarchy: name and year are the heading; small sentence-case headings mark the sections below. */
.card { position: fixed; z-index: 10; pointer-events: none; background: var(--panel); border-radius: 10px;
  width: 330px; max-height: calc(100vh - 24px); overflow-y: auto; box-shadow: 0 8px 28px rgba(30, 40, 50, .16); font-size: 13px; }
.card.pinned { pointer-events: auto; width: 400px; }
.card-close { position: absolute; top: 8px; right: 8px; width: 30px; height: 30px; border: 0; border-radius: 50%;
  background: color-mix(in srgb, var(--panel) 92%, transparent); cursor: pointer; font-size: 18px; line-height: 1; z-index: 1; }
.card .photo { margin: 0; }
.card .photo img { display: block; width: 100%; max-height: 210px; object-fit: cover; border-radius: 10px 10px 0 0; background: var(--bg); }
.card .photo figcaption { font-size: 11px; color: var(--muted); padding: 5px 16px 0; }
/* Photos through the years: today's first, then the archive; the year sits on the picture, tabs below jump. */
.card .photo .frame { position: relative; }
.card .photo .year { position: absolute; left: 10px; bottom: 8px; background: var(--ink); color: var(--panel);
  font-size: 12px; font-weight: 700; padding: 2px 7px; border-radius: 4px; font-variant-numeric: tabular-nums; }
.card .photo .prev, .card .photo .next { position: absolute; top: 50%; transform: translateY(-50%); width: 30px; height: 30px;
  border: 0; border-radius: 50%; background: rgba(255,255,255,.92); cursor: pointer; font-size: 20px; line-height: 1; }
.card .photo .prev { left: 8px; } .card .photo .next { right: 8px; }
.card .photo .years { display: flex; flex-wrap: wrap; gap: 4px; padding: 6px 16px 0; }
.card .photo .years button { border: 1px solid #d6d9dc; background: none; border-radius: 4px; padding: 2px 7px; font: inherit;
  font-size: 12px; cursor: pointer; font-variant-numeric: tabular-nums; }
.card .photo .years button[aria-current] { background: var(--ink); border-color: var(--ink); color: var(--panel); }
.card .photo button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.card .more-photos { font-size: 11px; margin: 3px 16px 0; color: var(--ink); }
.card a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 3px; }
/* The header band carries the period colour; --band-ink is black or white, whichever reads on it (app.js). */
.card-head { padding: 12px 16px 10px; background: var(--band, var(--panel)); color: var(--band-ink, var(--ink)); }
.card.pinned .card-head { padding-right: 46px; }
.card .card-head .period { color: inherit; }   /* full ink: faded, it fell under 4.5:1 on some bands */
.card .rating { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 6px; }
.card .rating.r1 { background: #2b6cb0; }
.card .rating.r2 { background: #2f855a; }
.card .rating.r3 { background: #d69e2e; }
.card-head h3 { margin: 0 0 6px; font-size: 17px; font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; padding-right: 26px; }
.card .when { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.card .y { font-size: 30px; font-weight: 800; letter-spacing: -0.03em; line-height: 1; }
.card .period { color: var(--muted); display: inline-flex; align-items: center; gap: 6px; }
.card .period i, .card .chips i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.card section { padding: 10px 16px; border-top: 1px solid var(--line); }
.card h4 { margin: 0 0 6px; font-size: 12px; font-weight: 700; color: var(--muted); }
.card .extract { margin: 0; line-height: 1.55; }
.card .fact { background: #fff6e8; border-top-color: #f0dcc0; }
.card .fact p { margin: 0; line-height: 1.5; }
.card .chips { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.card .chips li { display: flex; gap: 8px; align-items: flex-start; }
.card .chips li i { margin-top: 5px; }
.card .chips b { font-weight: 600; }
.card .chips span { color: var(--muted); }
.card .chips p { margin: 3px 0 0; line-height: 1.5; }
.card dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 0; }
.card dt { color: var(--muted); }
.card dd { margin: 0; text-align: right; }
.card .why { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.45; }
.card .sources p { margin: 0; }
.card .residents { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.card .residents span, .card .residents .desc { color: var(--muted); }
.card .residents blockquote { margin: 4px 0 0; padding-left: 10px; border-left: 2px solid var(--line); font-size: 12px; line-height: 1.5; color: #3e4448; }
.card .photo.inline { margin: 0 -16px -10px; }
.card .photo.inline img { border-radius: 0; }
.card .hint { margin: 0; padding: 8px 16px 12px; color: var(--muted); font-size: 12px; border-top: 1px solid var(--line); }
/* Plan 4a: how the year is known, one line under the band; the English label under the Swedish name; the excerpt's
   credit; a pinned card's photo above the band (its credit under it), sized before it loads so nothing jumps. */
.card .dating { margin: 0; padding: 8px 16px; color: var(--muted); font-size: 12px; line-height: 1.45; }
.card-head .en { margin: -4px 0 6px; font-size: 13px; }   /* its size, not a fade, sets it under the name */
.card-head .place { margin: -2px 0 8px; font-size: 13px; }   /* full ink, like .en: 4.5:1 on every band */
/* Google Maps as a pin at the end of the place line, in the band's own ink */
.card-head .place { display: flex; align-items: center; gap: 8px; }
.card-head .gmaps { display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; margin-left: auto; border-radius: 50%;
  color: inherit; background: color-mix(in srgb, currentColor 14%, transparent); }
.card-head .gmaps:hover, .card-head .gmaps:focus-visible { background: color-mix(in srgb, currentColor 26%, transparent); }
.card-head .gmaps svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linejoin: round; }
.card .extract .credit { margin: 6px 0 0; color: var(--muted); font-size: 11px; }
.card .photo img { height: auto; }   /* with the img's width and height attributes the browser keeps the room */
.card .photo figcaption { padding-bottom: 6px; line-height: 1.4; }
.card.pinned .photo + .card-head { padding-top: 10px; }
.card .sources a { white-space: nowrap; }

/* How to move: a quiet line under the timeline's right end. */
.howto { position: fixed; right: var(--gutter); bottom: calc(env(safe-area-inset-bottom, 0px) + 146px); color: var(--muted); background: color-mix(in srgb, var(--bg) 85%, transparent); padding: 2px 8px; border-radius: 4px;
  font-size: 12px; pointer-events: none; }
@media (max-width: 720px), (hover: none) { .howto { display: none; } }

.timeline { position: fixed; left: 0; right: 0; bottom: 0; display: flex; align-items: flex-end; gap: 14px;
  padding: 0 var(--gutter) calc(env(safe-area-inset-bottom, 0px) + 14px); pointer-events: none; }
.timeline > * { pointer-events: auto; }
/* min-width: 0 keeps the canvas out of the flex sizing: its bitmap (width × devicePixelRatio, rounded down) would
   otherwise set its minimum width, and at a fractional ratio (browser zoom) each redraw widened it a little. */
.hist-wrap { position: relative; flex: 1; min-width: 0; }
.timeline canvas { display: block; width: 100%; min-width: 0; height: 96px; cursor: ew-resize; touch-action: none; }
/* Plan 4a: the handles' grips, keyboard sliders over the histogram (app.js places them at their years). The pointer goes
   through them to the canvas, which drags the nearer handle as before. The from-grip at rest sits at the left end,
   faint, so it can be found. */
.grip { position: absolute; top: 0; width: 14px; height: 76px; margin-left: -7px; pointer-events: none; border-radius: 7px; }
.grip::before { content: ""; position: absolute; left: 3px; top: 2px; width: 8px; height: 14px; border-radius: 4px;
  background: var(--ink); box-shadow: 0 0 0 2px var(--bg); }
.grip-from::before { background: var(--muted); }
.grip-from.rest::before { opacity: .45; }   /* the knob only: its focus ring stays at full strength */
.grip:focus-visible { outline: 2px solid var(--accent); outline-offset: 0; }
.play { width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--ink); color: var(--panel);
  cursor: pointer; margin-bottom: 24px; display: grid; place-items: center; flex: none; }
.play svg { width: 16px; height: 16px; fill: currentColor; }

.loading { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); color: var(--muted); }
/* ?debug=1: renderer statistics, above the timeline on the right. */
.debug { position: fixed; right: var(--gutter); bottom: 150px; z-index: 30; padding: 8px 10px; border-radius: 6px;
  background: rgba(0, 0, 0, .78); color: #e6efe6; font: 11px/1.35 ui-monospace, Menlo, monospace; }
.debug pre { margin: 0 0 6px; font: inherit; }
.debug button { font: inherit; color: #111; margin-right: 6px; padding: 3px 8px; border: 0; border-radius: 4px; cursor: pointer; }

@media (max-width: 720px) {
  .dek { display: none; }
  h1 { font-size: 30px; }
  .tally-year { font-size: 30px; }
  .tally-year.named { font-size: 19px; max-width: 10em; margin-bottom: 2px; }
  .tally-count { font-size: 12px; }
  /* the name on its own line at the top, the buttons under it (they covered it, 2026-10-21) */
  .masthead { top: calc(env(safe-area-inset-top, 0px) + 10px); }
  .masthead h1 { font-size: 32px; }
  .corner { top: calc(env(safe-area-inset-top, 0px) + 56px); gap: 8px; }
  .sibling { top: calc(env(safe-area-inset-top, 0px) + 138px); }
  /* Modes: one scrolling strip above the timeline. */
  .modes { top: auto; left: 12px; right: 12px; transform: none; bottom: calc(env(safe-area-inset-bottom, 0px) + 100px);
    overflow-x: auto; scrollbar-width: none; justify-content: flex-start; }
  .modes::-webkit-scrollbar { display: none; }
  .modes button { flex: 1 0 auto; padding: 8px 11px; }
  /* Panel: a sheet above the modes, folded to its handle by default. */
  .panel { top: auto; left: 12px; right: 12px; width: auto; bottom: calc(env(safe-area-inset-bottom, 0px) + 156px);
    max-height: 48vh; padding: 0 14px 12px; }
  .sheet-handle { display: block; width: calc(100% + 28px); margin: 0 -14px 8px; padding: 12px 14px; border: 0;
    background: none; text-align: left; font-weight: 600; cursor: pointer; border-bottom: 1px solid var(--line); }
  .sheet-handle::after { content: ""; float: right; width: 8px; height: 8px; margin-top: 4px; border: solid var(--muted);
    border-width: 0 2px 2px 0; transform: rotate(225deg); }
  .panel.collapsed { overflow: hidden; padding-bottom: 0; }
  .panel.collapsed .sheet-handle { margin-bottom: 0; border-bottom: 0; }
  .panel.collapsed .sheet-handle::after { transform: rotate(45deg); margin-top: 0; }
  .panel.collapsed #panel-body { display: none; }
  /* Card: a sheet from the bottom edge. */
  .card, .card.pinned { left: 0 !important; right: 0; top: auto !important; bottom: 0; width: auto; max-height: 72vh;
    border-radius: 14px 14px 0 0; padding-bottom: env(safe-area-inset-bottom, 0px); }
  .card .photo img { border-radius: 14px 14px 0 0; max-height: 190px; }
  .timeline { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 10px); }
  .timeline canvas { height: 76px; }
  .grip { height: 56px; }
  .play { width: 40px; height: 40px; margin-bottom: 18px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* Look switcher (web/switcher.js): a popover under the Look button, a bottom sheet on a phone. Each card shows its
   look as it is: its panel colour, ink and font, and its twelve period colours on its own ground. */
.look-open { display: flex; align-items: center; gap: 6px; border: 0; border-radius: 999px; padding: 5px 11px 5px 9px;
  background: var(--panel); color: var(--ink); font-size: 12px; font-weight: 600; line-height: 18px; cursor: pointer; }
.look-open svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.look-open svg path { fill: currentColor; stroke: none; }
.look-open[aria-expanded="true"] { background: var(--ink); color: var(--panel); }
/* The dot on the Look button: a layer of "Show on the map" is on (web/switcher.js); gone while the panel is open. */
.look-open { position: relative; }
.look-dot { position: absolute; top: 1px; right: 1px; width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent, currentColor); box-shadow: 0 0 0 2px var(--panel); }
.look-open[aria-expanded="true"] .look-dot { display: none; }
.look-layers .est-row:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
/* The north button (web/north.js): round, as tall as the Look button and in its colours. The needle's north half is
   filled, its south half drawn; app.js turns the whole icon with the map (a transform, so no layout). */
.north-open { display: grid; place-items: center; flex: none; width: 28px; height: 28px; padding: 0; border: 0;
  border-radius: 50%; background: var(--panel); color: var(--ink); cursor: pointer; }
.north-open svg { width: 16px; height: 16px; }
.north-open .needle-n { fill: currentColor; }
.north-open .needle-s { fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linejoin: round; }
/* On a touch screen the top-right buttons take a tap a little outside what is drawn: 44 px tall targets, for the 28 px
   north and Look buttons and About's 24 px, without changing their size or the row. Sideways they reach halfway
   into the 6 px gap, so neighbours never overlap. The Look panel's Hills slider takes the same 44 px band (below). */
@media (pointer: coarse) {
  .north-open, .look-open, .search-open, .lang button { position: relative; }
  .north-open::after, .look-open::after, .search-open::after { content: ""; position: absolute; inset: -8px -3px; }
  .lang button::after { content: ""; position: absolute; inset: -10px 0; }
}
/* .corner is fixed, so it is its own stacking context: lift it over the legend and the card while the panel is open. */
.corner:has(.look[open]) { z-index: 25; }
/* The popover scrolls where the screen is shorter than it (a phone held sideways: 740 x 360 cut off the Ground row,
   VIEWER-1, and a short desktop window): its top sits 128 to 165 px down, so it may reach 180 px less than the
   screen's height. */
.look { position: absolute; inset: calc(100% + 8px) 0 auto auto; margin: 0; width: 308px; padding: 12px; border: 0;
  border-radius: 12px; background: var(--panel); color: var(--ink); box-shadow: 0 10px 34px rgba(30, 40, 50, .2);
  max-height: calc(100vh - 180px); max-height: calc(100dvh - 180px); overflow-y: auto; overscroll-behavior: contain; }
.look header { display: flex; align-items: center; justify-content: space-between; margin: 0 2px 10px; }
.look h2 { margin: 0; font-size: 13px; font-weight: 700; }
.look h3 { margin: 14px 2px 6px; font-size: 12px; font-weight: 600; color: var(--muted); }
.look-close { display: grid; width: 32px; height: 32px; margin: -6px -6px -6px 0; border: 0; border-radius: 50%;
  background: var(--bg); cursor: pointer; font-size: 18px; line-height: 1; place-items: center; }
.look-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.look-card { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 8px 8px 9px; border: 1px solid var(--line);
  border-radius: 9px; background: var(--card-bg); color: var(--card-ink); font-family: var(--card-font), sans-serif;
  text-align: left; cursor: pointer; }
.look-card:hover { border-color: var(--muted); }
.look-card[aria-pressed="true"] { border-color: transparent; box-shadow: 0 0 0 2px var(--accent); }
.look-strip { display: flex; gap: 2px; height: 28px; padding: 4px; border-radius: 5px; background: var(--card-ground); }
.look-strip i { flex: 1; border-radius: 1px; }
.look-name { font-size: 14px; font-weight: 700; letter-spacing: -0.01em; line-height: 1.2; padding: 0 2px; }
.look-check { display: none; position: absolute; top: -7px; right: -7px; width: 20px; height: 20px; }
.look-check circle { fill: var(--accent); stroke: var(--panel); stroke-width: 2; }
.look-check path { fill: none; stroke: var(--panel); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.look-card[aria-pressed="true"] .look-check { display: block; }
.look-atmos { display: flex; flex-wrap: wrap; gap: 6px; }
.look-atmos button { border: 1px solid var(--line); border-radius: 999px; background: none; padding: 5px 12px; font-size: 12px;
  font-weight: 600; cursor: pointer; }
.look-atmos button[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--panel); }
/* The Hills slider (Plan 3, D40): its label, a native range in the look's accent and its value ("Flat", "1.5×") on one
   24 px row, with the honesty line under it. When the terrain did not load the row is dimmed (aria-disabled), as the
   legend's switches are. */
.look-relief { display: flex; flex-direction: column; gap: 2px; padding: 0 2px; }
.relief-row { display: flex; align-items: center; gap: 10px; height: 24px; font-size: 13px; }
.relief-row label { flex: none; }
.relief-row input[type="range"] { flex: 1; min-width: 0; height: 24px; margin: 0; accent-color: var(--accent); cursor: pointer; }
.relief-row output { flex: none; min-width: 3.2em; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.relief-row:has(input[aria-disabled="true"]) { opacity: .45; }
.relief-row input[aria-disabled="true"] { cursor: default; }
/* The focus ring hugs the track, so it does not run over the line under the row (S8). On a touch screen the range is
   the 44 px band (below), so the ring goes round the row instead, the drawn size. */
.relief-row input[type="range"]:focus-visible { outline-offset: 0; }
.relief-note { color: var(--muted); font-size: 12px; line-height: 1.35; }
/* On a touch screen the slider takes a tap in a 44 px band (D36's), over its heading and its line, which take no tap:
   the range itself is 44 px tall (its track drawn in the middle, as on a desktop), and its margins give the 20 px
   back, so the row keeps its 24 px. Positioned, so it is hit before the line under it. */
@media (pointer: coarse) {
  .relief-row input[type="range"] { position: relative; height: 44px; margin: -10px 0; }
  .relief-row { padding: 0 6px; margin: 0 -6px; }   /* room inside the ring, the row's text where it was */
  .relief-row input[type="range"]:focus-visible { outline: none; }
  .relief-row:has(input[type="range"]:focus-visible) { outline: 2px solid var(--accent); outline-offset: 0; border-radius: 6px; }
}
@media (max-width: 720px) {
  .look { position: fixed; inset: auto 0 0 0; width: auto; max-height: 80vh; overflow-y: auto; border-radius: 16px 16px 0 0;
    padding: 16px 16px calc(env(safe-area-inset-bottom, 0px) + 18px); box-shadow: 0 -8px 30px rgba(30, 40, 50, .22); }
  .look header { margin-bottom: 12px; }
  .look h2 { font-size: 15px; }
  .look-close { display: grid; }
  .look-cards { gap: 10px; }
  .look-card { padding: 10px 10px 11px; gap: 10px; }
  .look-strip { height: 34px; }
  .look-name { font-size: 15px; }
}

/* About: a reading page over the map. */
.lang .about-open { color: var(--ink); }
.about { border: 0; border-radius: 12px; padding: 0; width: min(640px, calc(100vw - 32px)); max-height: calc(100vh - 48px);
  box-shadow: 0 20px 60px rgba(30, 40, 50, .25); background: var(--panel); color: var(--ink); overflow-y: auto; }
.about::backdrop { background: color-mix(in srgb, var(--bg) 70%, transparent); }
/* The dialog scrolls, not the article: an article that scrolls would shrink beside the floating close button. */
.about article { padding: 28px 32px 32px; }
.about h2 { margin: 0 0 12px; font-size: 26px; font-weight: 800; letter-spacing: -0.02em; }
.about h3 { margin: 22px 0 6px; font-size: 15px; font-weight: 700; }
.about p, .about li { line-height: 1.6; max-width: 64ch; }
.about ul { padding-left: 18px; margin: 6px 0 0; }
.about li { margin-bottom: 6px; }
.about a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; }
.about .credit { color: var(--muted); }
.about .author { font-weight: 600; margin-bottom: 4px; }
.about .author + .credit { margin-top: 0; }
.about .notice { border-left: 3px solid var(--accent); padding-left: 12px; font-weight: 500; }
.about-close { position: sticky; float: right; top: 10px; margin: 10px 10px 0 0; width: 32px; height: 32px; border: 0;
  border-radius: 50%; background: var(--bg); cursor: pointer; font-size: 18px; }
@media (max-width: 720px) { .about article { padding: 20px 18px 24px; } }
.contribute { margin: 14px 0 0; padding-top: 10px; border-top: 1px solid var(--line); font-size: 12px; }
.contribute a { color: var(--ink); text-decoration-color: var(--accent); text-underline-offset: 3px; }
.card .photo button[disabled] { opacity: .35; cursor: default; }
.card .photo .gone { position: absolute; inset: 0; margin: 0; display: grid; place-content: center; text-align: center; gap: 4px;
  padding: 0 40px; background: var(--bg); font-size: 12px; border-radius: 10px 10px 0 0; }
.card .photo.failed img { visibility: hidden; height: 190px; }

/* Quests (v1.1; hidden by config.features in v1). Every answer is worth three crosses. */
.modes .quests-open { display: inline-flex; align-items: center; gap: 7px; margin-left: 2px; border-left: 1px solid var(--line); border-radius: 0 999px 999px 0; }
.modes .quests-open svg { width: 18px; height: 6px; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; fill: none; }
.modes .quests-open:hover { background: #f1f3f4; }
.q-x { display: inline-flex; gap: 1px; font-weight: 800; font-size: 15px; line-height: 1; letter-spacing: -0.02em; }
.q-x i { font-style: normal; color: #d8dcde; }
.q-x i.on { color: var(--accent); }
.q-level { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; color: var(--muted); }
.q-level .q-x { font-size: 13px; }

.quests { width: min(980px, calc(100vw - 32px)); }
.quests article { padding: 24px 28px 26px; }
.quests h2 { margin: 0; }
.quests .q-lede { max-width: 70ch; margin: 6px 0 0; font-size: 13px; line-height: 1.5; }
.quests .q-score { font-size: 13px; color: var(--muted); margin: 6px 0 0; }
.quests .q-score b { color: var(--accent); font-size: 18px; }
.quests .q-grid { list-style: none; margin: 16px 0 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.quests .q-tile { margin: 0; max-width: none; line-height: 1.35; }
.q-tile { position: relative; display: flex; flex-direction: column; gap: 4px; padding: 14px 14px 12px; border-radius: 10px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.q-tile.l3 { box-shadow: inset 0 0 0 2px var(--ink); }
.q-tile h3 { margin: 2px 0 0; font-size: 15px; line-height: 1.25; letter-spacing: -0.01em; }
.q-tile p { margin: 0; color: #4b5257; font-size: 12px; line-height: 1.4; flex: 1; }
.q-tile footer { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; gap: 6px; }
.q-tile .q-progress { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.q-tile.complete::after { content: "×"; position: absolute; top: 6px; right: 12px; color: var(--accent); font-weight: 800; font-size: 20px; }
.quests .q-start { border: 0; background: var(--ink); color: var(--panel); border-radius: 999px; padding: 5px 12px; cursor: pointer; font-weight: 600; font-size: 12px; }
.q-tile.complete .q-start { background: var(--panel); color: var(--ink); box-shadow: inset 0 0 0 1.5px var(--ink); }

/* The open quest: a slip at the right, above the timeline. */
.quest { position: fixed; z-index: 11; right: var(--gutter); bottom: calc(env(safe-area-inset-bottom, 0px) + 146px); width: 350px; max-height: calc(100vh - 244px - env(safe-area-inset-bottom, 0px)); overflow-y: auto;
  background: var(--panel); border-radius: 12px; box-shadow: 0 10px 34px rgba(30, 40, 50, .2); font-size: 13px; }
.quest header { cursor: pointer; display: flex; align-items: center; gap: 10px; padding: 12px 44px 11px 16px; background: var(--ink); color: var(--panel);
  border-radius: 12px 12px 0 0; position: sticky; top: 0; z-index: 1; }
.quest header b { font-size: 14px; }
.quest header .q-level { margin-left: auto; color: #b9c0c4; }
.quest header .q-x i:not(.on) { color: #4a4f53; }
.quest .q-close { position: absolute; top: 6px; right: 6px; width: 30px; height: 30px; border: 0; border-radius: 50%; z-index: 2;
  background: none; color: var(--panel); cursor: pointer; font-size: 20px; line-height: 1; }
.quest .q-steps { display: flex; align-items: center; gap: 4px; padding: 10px 16px 0; }
.quest .q-steps i { width: 18px; height: 4px; border-radius: 2px; background: #dfe3e5; }
.quest .q-steps i.done { background: var(--accent); }
.quest .q-steps i.now { background: var(--ink); }
.quest .q-steps span { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.quest .q-photo { position: relative; margin: 10px 16px 0; overflow: hidden; height: 170px; border-radius: 8px; background: var(--bg); }
.quest .q-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.quest .q-photo .year { position: absolute; left: 8px; bottom: 8px; background: var(--ink); color: var(--panel); font-weight: 700; font-size: 12px; padding: 2px 7px; border-radius: 4px; }
.quest .q-credit { font-size: 11px; color: var(--muted); padding: 4px 16px 0; margin: 0; }
.quest .q-credit a, .quest .q-found a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 3px; }
.quest .q-riddle { margin: 0; padding: 10px 16px 0; font-size: 15px; line-height: 1.5; }
.quest .q-hints { margin: 8px 16px 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 4px; }
.quest .q-hints li { font-size: 13px; line-height: 1.45; padding-left: 10px; border-left: 2px solid var(--accent); }
.quest .q-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 12px 16px 14px; }
.quest .q-actions button, .quest .q-options button { border: 1px solid var(--line); background: var(--panel); border-radius: 999px;
  padding: 6px 13px; cursor: pointer; font-weight: 600; font-size: 12px; }
.quest .q-actions button small { color: var(--accent); font-weight: 800; }
.quest .q-actions .primary { background: var(--ink); border-color: var(--ink); color: var(--panel); }
.quest .q-worth { margin-left: auto; }
.quest .q-feedback { margin: 0; padding: 8px 16px 0; font-size: 13px; color: var(--muted); min-height: 1.4em; }
.quest .q-actions .q-feedback { padding: 0; }
.quest .q-feedback.hot { color: var(--accent); font-weight: 600; }
.quest .q-feedback.warm { color: #b45309; }
.quest .q-feedback.cold { color: #3f6b8f; }
.quest .q-feedback.miss { animation: q-shake .35s; }
/* year */
.quest .q-year { padding: 10px 16px 0; }
.quest .q-year output { display: block; font-size: 44px; font-weight: 800; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.quest .q-year input { width: 100%; margin: 10px 0 2px; accent-color: var(--accent); }
.quest .q-scale { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.quest .q-yeardiff { margin: 0 0 6px; }
/* choice */
.quest .q-options { display: flex; flex-direction: column; gap: 6px; padding: 12px 16px 0; }
.quest .q-options button { text-align: left; border-radius: 8px; padding: 9px 12px; font-size: 13px; font-weight: 500; }
.quest .q-options button:hover:not(:disabled) { border-color: var(--ink); }
.quest .q-options button.wrong { text-decoration: line-through; color: var(--muted); }
.quest .q-options button.right { background: var(--ink); color: var(--panel); border-color: var(--ink); }
/* the answer */
.quest .q-found { position: relative; margin: 14px 16px 0; padding: 14px 12px 10px; background: #f3f4f5; border-radius: 8px; }
.quest .q-found p { margin: 0; font-size: 13px; line-height: 1.5; }
.quest .q-found .q-earned { margin-top: 6px; font-size: 12px; color: var(--muted); }
.quest .q-found .q-earned:empty { display: none; }
.q-stamp { position: absolute; top: -12px; right: 10px; padding: 3px 8px; background: var(--panel); border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .12); animation: q-stamp .45s cubic-bezier(.2, 1.6, .4, 1); }
.q-stamp .q-x { font-size: 20px; }
.quest .q-then { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
.quest .q-then figure { margin: 0; position: relative; }
.quest .q-then img { width: 100%; height: 96px; object-fit: cover; border-radius: 6px; display: block; }
.quest .q-then figcaption { position: absolute; left: 5px; bottom: 5px; background: var(--ink); color: var(--panel); font-size: 11px; font-weight: 700; padding: 1px 6px; border-radius: 4px; }
/* the result */
.quest .q-result { padding: 18px 16px 4px; }
.quest .q-total { margin: 0; font-size: 15px; color: var(--muted); }
.quest .q-total b { font-size: 48px; font-weight: 800; letter-spacing: -0.04em; color: var(--ink); }
.quest .q-verdict { margin: 2px 0 0; font-size: 16px; font-weight: 700; }
.quest .q-line { margin: 10px 0 0; font-size: 20px; font-weight: 800; color: var(--accent); letter-spacing: 0.04em; word-spacing: 0.3em; }
@keyframes q-stamp { from { transform: rotate(-20deg) scale(2); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes q-shake { 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
.quest.folded > :not(header):not(.q-close):not(.q-steps) { display: none; }
.quest.folded .q-steps { padding-bottom: 10px; }
@media (max-width: 720px) {
  .quest { left: 12px; right: 12px; width: auto; bottom: auto; top: calc(env(safe-area-inset-top, 0px) + 102px); max-height: 50vh; }
  .quest .q-photo { height: 120px; }
  /* On a phone the quests are a list: level and title on the left, progress and the button on the right. */
  .quests .q-grid { grid-template-columns: 1fr; gap: 6px; }
  .quests article { padding: 20px 16px; }
  .quests .q-lede { font-size: 12px; }
  .q-tile { display: grid; grid-template-columns: 1fr auto; column-gap: 10px; row-gap: 2px; align-items: center; padding: 10px 12px; }
  .q-tile .q-level { grid-column: 1; grid-row: 1; }
  .q-tile h3 { grid-column: 1; grid-row: 2; margin: 0; }
  .q-tile p { display: none; }
  .q-tile footer { grid-column: 2; grid-row: 1 / span 2; margin: 0; gap: 10px; }
  .q-tile.complete::after { display: none; }
  /* During a quest the phone shows the map and the riddle only; colour hints switch modes from the riddle itself. */
  body.questing .panel, body.questing .modes, body.questing .timeline, body.questing .buttons, body.questing .tally { display: none; }
  body.questing .quest { top: calc(env(safe-area-inset-top, 0px) + 62px); max-height: 56vh; }
  /* Quests stay in the strip, a tab like Walk: Stockholm's strip has two colourings, not Amsterdam's four, so it fits;
     the pill upstream pins opposite the language switch would sit on our search and north buttons (2026-10-18). */
  .modes .quests-open { margin: 0; border-left: 0; border-radius: 999px; }
  .modes .quests-open svg { display: none; }
}
@media (prefers-reduced-motion: reduce) { .quest .q-feedback.miss, .q-stamp { animation: none; } }

/* Walks (app.js Walks, web/walk.js): the planner reuses the quests dialog, the walk the quest panel. */
.modes .walks-open { white-space: nowrap; }
.walks .w-go { margin: 18px 0 0; }
.walks .w-make { font: inherit; font-weight: 600; padding: 9px 18px; border: 0; border-radius: 999px; cursor: pointer;
  background: var(--ink); color: var(--panel); min-height: 44px; }
.walks h3 { margin: 16px 0 6px; font-size: 13px; }
.w-lede, .w-note { font-size: 13px; line-height: 1.45; margin: 4px 0; opacity: .8; }
.w-msg { font-size: 13px; margin: 12px 0 0; padding: 8px 10px; border-left: 3px solid var(--accent); background: #f1f3f4; }
.w-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.w-chip { font: inherit; font-size: 13px; padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel); color: var(--ink); cursor: pointer; }
.w-chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--panel); }
.w-go { margin-top: 18px; }
.walk header span { display: block; font-size: 12px; font-weight: 400; opacity: .75; }
.w-list { list-style: none; margin: 8px 0; padding: 0; max-height: 40vh; overflow: auto; }
.w-list button { display: block; width: 100%; text-align: left; font: inherit; font-size: 13px; padding: 6px 0;
  border: 0; border-bottom: 1px solid var(--line); background: none; color: var(--ink); cursor: pointer; }
.w-list button span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; opacity: .75; }
.walk .w-google { text-decoration: none; }
/* The walk's own parts take the quest panel's 16 px inset; its Google Maps link is a pill like the panel's buttons. */
.walk .w-note { margin: 0; padding: 10px 16px 0; font-size: 13px; line-height: 1.45; color: var(--muted); }
.walk .w-list { list-style: none; margin: 8px 0 0; padding: 0 16px; }
.walk .w-list li + li { border-top: 1px solid var(--line); }
.walk .w-list button { display: grid; gap: 2px; width: 100%; padding: 8px 0; border: 0; background: none; color: inherit;
  font: inherit; font-size: 13px; text-align: left; cursor: pointer; }
.walk .w-list button span { color: var(--muted); font-size: 12px; }
.walk .w-list button:hover b { color: var(--accent); }
.quest .q-actions a { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: 999px;
  padding: 6px 13px; font-weight: 600; font-size: 12px; color: inherit; }
.quest .q-actions a.primary { background: var(--ink); border-color: var(--ink); color: var(--panel); }
@media (max-width: 720px) {
  body.walking .timeline, body.walking .tally { display: none; }
  .walk { max-height: 50vh; }
}

/* Search (Plan 4b, web/searchbox.js): a pill beside the modes on a desktop (app.js placeSearch sets its left edge),
   under them on a narrow desktop, a full-screen sheet on a phone. */
.search { position: fixed; top: calc(env(safe-area-inset-top, 0px) + var(--gutter)); left: calc(50% + 140px); z-index: 12;
  width: 280px; transition: width .15s; }
.search:focus-within { width: 340px; }
.search-box { display: flex; align-items: center; gap: 6px; height: 36px; padding: 0 6px 0 12px; border-radius: 999px;
  background: var(--panel); box-shadow: 0 1px 0 var(--line); }
.search-box svg { width: 14px; height: 14px; flex: none; fill: none; stroke: var(--muted); stroke-width: 1.8; stroke-linecap: round; }
.search-box input { flex: 1; min-width: 0; height: 100%; border: 0; background: none; font: inherit; color: var(--ink); outline: none; }
.search-box input::-webkit-search-cancel-button { display: none; }
.search-box:focus-within { box-shadow: 0 0 0 2px var(--accent); }
.search-key { font: 600 11px/1 var(--font), sans-serif; color: var(--muted); border: 1px solid var(--line); border-radius: 4px; padding: 2px 5px; }
.search:focus-within .search-key, .search.filled .search-key { display: none; }
.search-clear { display: none; width: 26px; height: 26px; border: 0; border-radius: 50%; background: none; color: var(--muted);
  font-size: 17px; line-height: 1; cursor: pointer; }
.search.filled .search-clear { display: block; }
.search-cancel { display: none; }
.search-list { list-style: none; margin: 6px 0 0; padding: 4px; max-height: 60vh; overflow-y: auto; border-radius: 10px;
  background: var(--panel); box-shadow: 0 10px 34px rgba(30, 40, 50, .2); }
.search-list li { display: grid; grid-template-columns: 10px 1fr; gap: 1px 10px; padding: 7px 10px; border-radius: 7px; cursor: pointer; }
.search-list li[aria-selected="true"] { background: color-mix(in srgb, var(--accent) 16%, var(--panel)); }
.search-list .sw { grid-row: span 2; width: 10px; height: 10px; margin-top: 4px; border-radius: 2px; background: var(--line); }
.search-list .sw.kind-street { height: 3px; margin-top: 8px; background: var(--muted); }
.search-list .sw.kind-district { border-radius: 50%; border: 2px solid var(--muted); background: none; }
.search-list b { font-weight: 700; }
.search-list .sub { font-size: 12px; color: var(--muted); }
.search-msg { margin: 6px 0 0; padding: 10px 12px; border-radius: 10px; background: var(--panel); font-size: 13px; line-height: 1.5;
  box-shadow: 0 10px 34px rgba(30, 40, 50, .12); }
.search-try { padding: 0; border: 0; background: none; font: inherit; color: var(--ink); text-decoration: underline;
  text-decoration-color: var(--accent); text-underline-offset: 3px; cursor: pointer; }
.search-open { display: none; }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.card .picked { margin: 0; padding: 8px 16px; font-size: 12px; color: var(--muted); border-top: 1px solid var(--line); }
@media (max-width: 1100px) and (min-width: 721px) {
  .search { left: 50% !important; transform: translateX(-50%); top: calc(env(safe-area-inset-top, 0px) + var(--gutter) + 46px); }
}
@media (max-width: 720px) {
  .search { display: none; inset: 0; width: auto; z-index: 40; overflow-y: auto; background: var(--bg);
    padding: calc(env(safe-area-inset-top, 0px) + 12px) 12px 12px; }
  .search.open { display: block; }
  .search:focus-within { width: auto; }
  .search-box { height: 44px; }
  /* 16 px or more, or iPhone Safari zooms the page when the field takes the focus, and leaves it zoomed */
  .search-box input { font-size: 16px; }
  .search-cancel { display: block; padding: 0 6px; border: 0; background: none; font: inherit; font-weight: 600; color: var(--ink); cursor: pointer; }
  .search-key { display: none; }
  .search-list, .search-msg { box-shadow: none; max-height: none; }
  .search-open { display: grid; place-items: center; flex: none; width: 28px; height: 28px; padding: 0; border: 0;
    border-radius: 50%; background: var(--panel); color: var(--ink); cursor: pointer; }
  .search-open svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
  .search-open[hidden] { display: none; }
}

/* About, written from the build (Plan 4b, web/about.js): section links, tables that scroll on a phone. */
.about .lead { font-size: 16px; }
.about-nav { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 6px; }
.about-nav a { padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; font-size: 12px; font-weight: 600;
  text-decoration: none; }
.about h3[tabindex] { scroll-margin-top: 52px; }   /* below the sticky close button (10 + 32 + 10 px) */
.about h3[tabindex]:focus { outline: none; }
.about .table { overflow-x: auto; margin: 8px 0; }
.about table { border-collapse: collapse; font-size: 13px; min-width: 100%; }
.about th, .about td { padding: 4px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.about td:not(:first-child), .about th:not(:first-child) { text-align: right; }
/* numbers never break; the headings and the last column's words wrap, so the accuracy table fits a desktop's dialog */
.about td:not(:first-child):not(:last-child) { white-space: nowrap; }
.about tr.total td { font-weight: 700; border-bottom: 0; }
.about details { margin: 8px 0; }
.about summary { cursor: pointer; font-weight: 600; }
.about-close { color: var(--ink); }   /* not the browser's ButtonText, which a dark look would hide */
.card .dating .why { margin-left: 4px; font-size: 12px; white-space: nowrap; }
.card .share { margin: 0; padding: 8px 16px; border-top: 1px solid var(--line); }
.card .share button { font: inherit; font-size: 13px; padding: 4px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: inherit; cursor: pointer; }
.card .wrong { margin: 0; padding: 8px 16px 12px; border-top: 1px solid var(--line); font-size: 12px; }
.card .wrong button { font: inherit; padding: 0; border: 0; background: none; color: var(--muted); cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }
.about .report-open { font: inherit; padding: 6px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: inherit; cursor: pointer; }

/* The report form (web/report-form.js): About's surface, one column, big enough targets for a thumb. */
.report form { padding: 24px 28px 28px; display: grid; gap: 6px; }
.report h2 { margin: 0 0 8px; font-size: 22px; font-weight: 800; }
.report h3 { margin: 0 0 4px; font-size: 14px; }
.report-ref { padding: 10px 12px; border-radius: 8px; background: var(--bg); }
.report-ref dl { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 2px 12px; font-size: 13px; }
.report-ref dt { color: var(--muted); }
.report-ref dd { margin: 0; }
.report fieldset { border: 1px solid var(--line); border-radius: 8px; margin: 8px 0; padding: 8px 12px 10px; display: grid; gap: 6px; }
.report legend { font-weight: 700; padding: 0 4px; }
.report label { font-weight: 600; margin-top: 6px; }
.report .report-kind, .report .report-check { font-weight: 400; display: flex; gap: 8px; align-items: flex-start; min-height: 32px; }
.report .report-kind input, .report .report-check input { margin-top: 3px; width: 18px; height: 18px; flex: none; }
.report textarea, .report input[type="text"], .report input[type="email"] { font: inherit; padding: 8px 10px; border-radius: 6px;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink); width: 100%; box-sizing: border-box; }
.report [aria-invalid="true"] { border-color: #c0392b; outline: 2px solid #c0392b; }
.report-note { margin: 0; font-size: 12px; color: var(--muted); }
.report-hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.report-status:empty { display: none; }
.report-status { margin: 6px 0 0; font-weight: 600; }
.report-actions { display: flex; gap: 8px; margin: 10px 0 0; }
.report-actions button { font: inherit; padding: 8px 18px; border-radius: 999px; border: 1px solid var(--line); cursor: pointer;
  background: transparent; color: inherit; min-height: 40px; }
.report-actions .report-send, .report-actions .report-done { background: var(--ink); color: var(--panel); border-color: var(--ink); }
.report-address { font-weight: 600; margin: 0; }
@media (max-width: 720px) { .report form { padding: 18px 16px 22px; } }

/* The corner credit (Plan 4b, web/credits.js): under the drag hint and above the timeline on a desktop; on a phone
   under the buttons in the sky, folding into its (i) button after 5 s. */
.credits { position: fixed; right: var(--gutter); bottom: calc(env(safe-area-inset-bottom, 0px) + 120px); z-index: 5;
  pointer-events: none; }   /* its empty width is the map's: a drag or a tap there reaches the canvas */
.credits > * { pointer-events: auto; }
.credit-line { margin: 0; padding: 2px 8px; border-radius: 4px; font-size: 11px; color: var(--muted);
  background: color-mix(in srgb, var(--bg) 85%, transparent); }
.credit-line a { color: inherit; text-decoration-color: var(--line); text-underline-offset: 2px; }
.credit-open { width: 26px; height: 26px; border: 0; border-radius: 50%; background: var(--panel); color: var(--ink);
  font: italic 700 13px/1 Georgia, serif; cursor: pointer; }
.credits.folded .credit-line { display: none; }
@media (max-width: 720px) {
  .credits { bottom: auto; top: calc(env(safe-area-inset-top, 0px) + 112px); right: 12px; left: 12px; text-align: right; }   /* app.js placeCredit sets top under the corner */
  .credit-line { display: inline-block; }
}
/* The middle of the screen while the map has the keyboard (the audit's finding 1): Enter opens the building under it. */
.crosshair { display: none; position: fixed; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
  pointer-events: none; z-index: 2;
  background: linear-gradient(var(--ink), var(--ink)) center / 2px 100% no-repeat, linear-gradient(var(--ink), var(--ink)) center / 100% 2px no-repeat;
  filter: drop-shadow(0 0 1.5px var(--panel)); }
#scene:focus-visible ~ .crosshair { display: block; }
#scene:focus-visible { outline-offset: -4px; }
.card .card-failed { color: var(--ink); font-weight: 500; }

/* Launch check (phones): on a touch screen every control takes a tap in at least 44 × 44 px. Rows and pills grow to
   it; the small round buttons keep their drawn size and take the tap in an invisible band around it (::after), as
   the top-right buttons do above. Links inside running text are exempt (WCAG 2.5.8, inline). */
@media (pointer: coarse) {
  .modes button, .swatch, .swatch.unknown .switch, .est-row .switch, .sheet-handle, .search-cancel,
  .about-nav a, .look-atmos button, .card .photo .years button { min-height: 44px; }
  .about-nav a { display: inline-flex; align-items: center; }
  .search-clear { width: 44px; height: 44px; }
  /* the round top-right buttons take a full 44 px band on every side: a 16 px gap keeps the bands apart */
  .buttons { gap: 16px; }
  .north-open::after, .search-open::after { inset: -8px; }
  .lang button { min-width: 44px; }
  .play { width: 44px; height: 44px; }
  .look-close { position: relative; }
  .card-close::after, .about-close::after, .look-close::after, .credit-open::after,
  .card .photo .prev::after, .card .photo .next::after { content: ""; position: absolute; inset: -7px; }
  .credit-open { position: relative; }
  .credit-open::after { inset: -9px; }
}
/* Samfundet S:t Erik's blue plaques (features.plaques): the plaque's own blue edge, its credit like the excerpt's. */
.card .plaque { border-left: 4px solid #1f4e9c; }
.card .plaque p { margin: 0 0 6px; line-height: 1.5; }
.card .plaque .plaque-name { font-weight: 600; }
.card .plaque .credit { margin: 0; color: var(--muted); font-size: 11px; }
.card .plaque .plaque-note { color: var(--muted); font-size: 11px; font-style: italic; }
/* The top-right labels stay on one line ("Om kartan", "Berättelser" on a 375 px phone fit in one row). */
.about-open, .stories-open, .look-open { white-space: nowrap; }

/* A metro station's card (web/metro.js stationCard): its lines as small swatches in our own line colours. */
/* A station's card (web/metro.js stationCard) has no sections of its own, so it takes the building card's inset itself. */
#card.station { padding: 14px 16px 12px; }
#card.station h3 { margin: 0 0 8px; padding-right: 30px; font-size: 17px; font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; }
#card.station p { margin: 0 0 6px; }
#card.station p:last-child { margin-bottom: 0; }
#card .metro-lines { display: flex; flex-wrap: wrap; gap: 4px 12px; }
#card .metro-line { display: inline-flex; align-items: center; gap: 6px; }
#card .metro-line i { width: 14px; height: 4px; border-radius: 2px; }
#card .metro-formerly { color: var(--muted); }
/* On a narrow phone the corner's row (search, north, Look, Stories, About, EN | SV) wraps right-aligned onto a second
   line rather than pushing the first buttons off the left edge (e2e/credits.spec.mjs checks 390 and 360 px). The 18 px
   between the lines keeps the touch bands apart (Look's reaches 8 px down, About's 10 px up), so a tap just under Look
   is still Look (e2e/smoke.spec.mjs). */
@media (max-width: 430px) { .corner .buttons { flex-wrap: wrap; justify-content: flex-end; row-gap: 18px; } }

.card .photo.hover img { max-height: 160px; }
.card .photo.hover figcaption { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding-bottom: 4px; }
.card .photo.hover + .card-head { padding-top: 8px; }

/* Story walks (app.js Story walks): cards in the walks dialog, and the story panel at the left of the map. */
.walks .s-head { margin: 18px 0 8px; font-size: 13px; }
.walks .s-own { margin-top: 26px; padding-top: 16px; border-top: 1px solid var(--line); }
.s-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.s-card { display: flex; flex-direction: column; text-align: left; padding: 0; border: 1px solid var(--line); border-radius: 12px;
  overflow: hidden; background: var(--panel); color: inherit; font: inherit; cursor: pointer; transition: transform .15s, box-shadow .15s; }
.s-card:hover { transform: translateY(-2px); box-shadow: 0 8px 22px rgba(20, 30, 40, .14); }
.s-card img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; background: #2a1d17; }
.s-card-body { display: grid; gap: 3px; padding: 10px 12px 12px; }
.s-card-body b { font-size: 15px; line-height: 1.2; }
.s-dek { color: var(--muted); font-size: 13px; line-height: 1.35; }
.s-meta { font-size: 12px; color: var(--accent); font-weight: 600; }
.walks .s-ill { margin-top: 6px; font-size: 11px; }
@media (max-width: 720px) { .s-cards { grid-template-columns: 1fr; } .s-card { flex-direction: row; } .s-card img { width: 38%; aspect-ratio: auto; } }

.tour { position: fixed; z-index: 12; left: var(--gutter); top: 128px; bottom: calc(env(safe-area-inset-bottom, 0px) + 112px); width: min(480px, 36vw);
  overflow-y: auto; background: var(--panel); border-radius: 14px; box-shadow: 0 12px 38px rgba(20, 30, 40, .22); font-size: 14px; line-height: 1.55; }
body.storying #panel { display: none; }
.tour .s-x { position: absolute; top: 8px; right: 8px; z-index: 3; width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .92); color: var(--ink); font-size: 20px; line-height: 1; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,.2); }
.tour .s-cover { margin: 0; }
.tour .s-cover img { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 14px 14px 0 0; }
.tour .s-body { padding: 4px 20px 14px; }
.tour .s-body p { margin: 0 0 10px; }
.tour h2 { font-size: 22px; line-height: 1.2; margin: 12px 0 6px; letter-spacing: -.01em; }
.tour h3 { font-size: 13px; margin: 16px 0 4px; }
.tour .s-kicker { margin: 14px 0 0 !important; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--accent); font-weight: 700; }
.tour .s-dek { font-size: 15px; margin-bottom: 4px !important; }
.tour .s-top { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 10px; padding: 12px 48px 10px 16px;
  background: var(--ink); color: var(--panel); border-radius: 14px 14px 0 0; }
.tour .s-all { border: 0; background: none; color: inherit; font: inherit; font-weight: 700; padding: 0; cursor: pointer; text-align: left; }
.tour .s-all:hover { text-decoration: underline; }
.tour .s-steps { display: flex; gap: 3px; margin-left: auto; }
.tour .s-steps i { width: 14px; height: 4px; border-radius: 2px; background: #4a5156; }
.tour .s-steps i.done { background: #9aa3a8; } .tour .s-steps i.on { background: var(--accent); }
.tour .s-count { font-size: 12px; opacity: .8; white-space: nowrap; }
.tour .s-photo { margin: 0; position: relative; }
.tour .s-photo img { display: block; width: 100%; height: auto; max-height: 360px; object-fit: cover; background: #e9e4dc; filter: saturate(.92); }
.tour .s-photo .s-yr { position: absolute; left: 12px; top: 12px; background: var(--ink); color: var(--panel); font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 4px; }
.tour .s-photo figcaption { font-size: 11px; line-height: 1.4; color: var(--muted); padding: 6px 20px 0; }
.tour .s-photo figcaption a, .tour .s-src a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 2px; }
.tour .s-look { margin: 12px 0; padding: 10px 12px; border-left: 3px solid var(--accent); background: #faf6f1; border-radius: 0 8px 8px 0; }
.tour .s-look b { display: block; font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--accent); }
.tour .s-look p { margin: 2px 0 0 !important; font-size: 13px; }
.tour .s-next { font-style: italic; color: var(--muted); }
.tour .s-src { font-size: 11px; color: var(--muted); }
.tour .s-nav { display: flex; gap: 8px; align-items: center; }
.tour .s-bar { position: sticky; bottom: 0; padding: 10px 20px 12px; background: linear-gradient(to top, var(--panel) 75%, rgba(255,255,255,0)); justify-content: space-between; }
.tour .s-nav button, .tour .s-route { font: inherit; font-size: 13px; font-weight: 600; padding: 8px 14px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); cursor: pointer; }
.tour .s-nav .primary { background: var(--ink); border-color: var(--ink); color: var(--panel); }
.tour .s-more { padding: 0 20px 16px; font-size: 13px; }
.tour .s-more summary { cursor: pointer; color: var(--muted); }
.tour .s-list { list-style: none; margin: 6px 0 0; padding: 0; }
.tour .s-list button { display: flex; gap: 10px; align-items: center; width: 100%; padding: 7px 0; border: 0; border-top: 1px solid var(--line);
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.tour .s-list i { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--accent); color: #fff; font-style: normal; font-size: 12px; font-weight: 700; }
.tour .s-list [aria-current] i { background: var(--ink); }
.tour .s-list button:hover span { color: var(--accent); }
@media (max-width: 720px) {
  .tour { left: 0; right: 0; width: auto; top: auto; bottom: 0; max-height: 46vh; border-radius: 16px 16px 0 0; font-size: 14px; }
  .tour .s-top, .tour .s-cover img { border-radius: 16px 16px 0 0; }
  .tour .s-photo img { max-height: 180px; }
  .tour .s-cover img { aspect-ratio: 16 / 7; }
  body.storying .timeline { display: none; }
}

/* Then and now (photoSwitch) and the walks' Fördjupning */
.ph-switch { position: relative; }
.ph-switch .ph-slide { display: none; position: relative; }
.ph-switch .ph-slide.on { display: block; animation: phfade .45s ease; }
@keyframes phfade { from { opacity: 0; } to { opacity: 1; } }
.ph-tabs { position: absolute; right: 10px; top: 10px; display: flex; gap: 2px; padding: 3px; border-radius: 999px; background: rgba(18, 26, 33, .72); backdrop-filter: blur(4px); z-index: 2; }
.ph-tabs button { border: 0; background: none; color: #fff; font: inherit; font-size: 12px; font-weight: 600; padding: 4px 11px; border-radius: 999px; cursor: pointer; }
.ph-tabs button[aria-selected="true"] { background: #fff; color: var(--ink); }
.card .ph-tabs { top: 8px; right: auto; left: 10px; pointer-events: auto; }
.card.pinned .ph-switch .ph-slide figcaption { padding: 5px 16px 0; }
.tour .s-deep { margin: 14px 0 4px; border-top: 1px solid var(--line); padding-top: 10px; }
.tour .s-deep > summary { cursor: pointer; font-weight: 700; font-size: 14px; list-style: none; display: flex; align-items: center; gap: 8px; }
.tour .s-deep > summary::before { content: '+'; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--ink); color: var(--panel); font-size: 15px; }
.tour .s-deep[open] > summary::before { content: '–'; }
.tour .s-thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.tour .s-thumb { position: relative; padding: 0; border: 2px solid transparent; border-radius: 8px; overflow: hidden; cursor: pointer; background: #eee; aspect-ratio: 4 / 3; }
.tour .s-thumb.on { border-color: var(--accent); }
.tour .s-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; filter: saturate(.9); }
.tour .s-thumb span { position: absolute; left: 4px; bottom: 4px; background: rgba(18,26,33,.75); color: #fff; font-size: 10px; padding: 1px 5px; border-radius: 3px; }
.tour .s-thumb-view { margin-top: 8px; }
.tour .s-thumb-view .s-photo figcaption { padding: 6px 0 0; }
.tour .s-people { list-style: none; margin: 0; padding: 0; }
.tour .s-people li { display: grid; padding: 5px 0; border-top: 1px solid var(--line); font-size: 13px; line-height: 1.35; }
.tour .s-people li span { color: var(--muted); font-size: 12px; }
.tour .s-facts { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; font-size: 13px; margin: 0; }
.tour .s-facts dt { color: var(--muted); } .tour .s-facts dd { margin: 0; }
.tour .s-card-open { font: inherit; font-size: 13px; font-weight: 600; padding: 7px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); cursor: pointer; margin-top: 8px; }

/* Story mode (app.js storyMode): film bars from above and below, the chrome steps aside */
.cine { position: fixed; inset: 0; pointer-events: none; z-index: 11; }
.cine i { position: absolute; left: 0; right: 0; height: 0; background: #05070a; transition: height 1.6s cubic-bezier(.65, 0, .35, 1); }
.cine-t { top: 0; } .cine-b { bottom: 0; }
body.cinema .cine i { height: 9vh; }
.modes, .search, .corner, .timeline, .tally, #panel, .credits, .hint, .north, .switcher { transition: opacity .8s ease, transform .8s ease; }
body.cinema .modes, body.cinema .search, body.cinema .timeline, body.cinema .tally, body.cinema .credits, body.cinema .hint { opacity: 0; pointer-events: none; }
body.cinema .corner { opacity: .0; pointer-events: none; }
body.cinema .tour { top: calc(9vh + 18px); bottom: calc(9vh + 18px); background: rgba(16, 20, 28, .82); color: #eef0f2; backdrop-filter: blur(10px);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .45); --ink: #eef0f2; --muted: #a9b1b8; --line: rgba(255,255,255,.14); --panel: #141a22; }
body.cinema .tour .s-top { background: rgba(0,0,0,.35); }
body.cinema .tour .s-look { background: rgba(255,255,255,.06); }
body.cinema .tour .s-bar { background: linear-gradient(to top, rgba(16,20,28,.95) 70%, rgba(16,20,28,0)); }
body.cinema .tour .s-nav button { background: transparent; color: #eef0f2; border-color: rgba(255,255,255,.25); }
body.cinema .tour .s-nav .primary { background: #eef0f2; color: #10141c; border-color: #eef0f2; }
body.cinema .tour h2 { font-family: Georgia, 'Times New Roman', serif; font-weight: 500; font-size: 26px; }
body.cinema .tour .s-list button, body.cinema .tour .s-deep summary { color: inherit; }
@media (max-width: 720px) { body.cinema .cine i { height: 6vh; } body.cinema .tour { top: auto; bottom: 6vh; } }
body.cinema .tour .s-top, body.cinema .tour .s-all, body.cinema .tour .s-count { color: #eef0f2; }
body.cinema .tour .s-x { background: rgba(255,255,255,.14); color: #eef0f2; box-shadow: none; }
body.cinema .ph-tabs button { color: #eef0f2; }
body.cinema .ph-tabs button[aria-selected="true"] { background: #eef0f2; color: #10141c; }
body.cinema .tour .s-photo figcaption { color: #a9b1b8; }
body.cinema .brand, body.cinema header.top, body.cinema h1 { opacity: 0; transition: opacity .8s ease; pointer-events: none; }
/* Story mode: only the story — every other control and label steps out */
body.cinema .masthead, body.cinema .modes, body.cinema .search, body.cinema .corner, body.cinema #panel, body.cinema .howto,
body.cinema .credits, body.cinema .timeline, body.cinema .card:not(.pinned), body.cinema .crosshair, body.cinema .veil {
  opacity: 0 !important; pointer-events: none !important; transition: opacity .8s ease; }
.masthead, .howto, .card { transition: opacity .8s ease; }

.s-mapyear { margin: 0 0 4px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; opacity: .7; }

.s-card-own { background: color-mix(in srgb, var(--accent) 8%, var(--panel)); border-style: dashed; }
.s-own-art { display: grid; place-items: center; aspect-ratio: 16 / 10; color: var(--accent);
  background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--accent) 10%, transparent) 0 1px, transparent 1px 14px); }
.s-own-art svg { width: 60%; fill: currentColor; }
.w-back { all: unset; cursor: pointer; font-weight: 700; font-size: 14px; color: var(--muted); margin-bottom: 8px; display: inline-block; }
@media (max-width: 720px) { .s-own-art { width: 38%; aspect-ratio: auto; } }

/* People: the map's pins (web/people.js, app.js ppMap) and the chrome the panel replaces */
body.peopling #panel, body.peopling .timeline, body.peopling .howto, body.peopling .masthead, body.peopling .search,
body.peopling .credits, body.peopling #card { display: none !important; }
.pp-pins { position: fixed; inset: 0; pointer-events: none; z-index: 25; }
.pp-pin { position: absolute; left: 0; top: 0; pointer-events: auto; border: 0; background: none; padding: 0; cursor: pointer;
  font: inherit; color: var(--ink); width: 0; height: 0; overflow: visible; }
.pp-pin-in { position: absolute; left: 0; bottom: 0; translate: -50% 0; display: flex; flex-direction: column; align-items: center; }
.pp-pin-faces { display: flex; padding: 3px; background: var(--panel); border-radius: 999px; box-shadow: 0 4px 14px rgba(0,0,0,.25); position: relative; }
.pp-pin-faces::after, .pp-pin-n::after { content: ''; position: absolute; left: 50%; bottom: -6px; translate: -50% 0; border: 6px solid transparent;
  border-bottom: 0; border-top-color: var(--panel); }
.pp-pin-face { width: 34px; height: 34px; border-radius: 50%; overflow: hidden; display: grid; place-items: center; background: #d9d4cc; font-weight: 700;
  border: 2px solid var(--panel); margin-left: -10px; font-size: 13px; }
.pp-pin-face:first-child { margin-left: 0; }
.pp-pin-face img { width: 100%; height: 100%; object-fit: cover; }
.pp-pin-more { align-self: center; font-size: 11px; font-weight: 700; padding: 0 6px; }
.pp-pin-n { position: relative; width: 30px; height: 30px; border-radius: 50%; background: var(--accent); color: #fff; display: grid; place-items: center;
  font-weight: 800; font-size: 14px; box-shadow: 0 4px 14px rgba(0,0,0,.3); }
.pp-pin-n::after { border-top-color: var(--accent); }
.pp-pin.on .pp-pin-n { background: var(--ink); width: 36px; height: 36px; }
.pp-pin.on .pp-pin-n::after { border-top-color: var(--ink); }
.pp-pin-label { display: none; margin-bottom: 10px; background: var(--panel); border-radius: 8px; padding: 6px 10px; box-shadow: 0 6px 18px rgba(0,0,0,.2);
  width: max-content; max-width: 240px; text-align: left; font-size: 12.5px; line-height: 1.35; white-space: normal; }
.pp-pin-label b { display: block; font-size: 13px; }
.pp-pin-label em { display: block; font-style: normal; font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--accent); }
.pp-pin-label span { display: block; margin-top: 3px; font-family: Georgia, serif; font-size: 14px; }
.pp-pin:hover .pp-pin-label, .pp-pin:focus-visible .pp-pin-label, .pp-pin.person .pp-pin-label { display: block; }
.pp-pin.on { z-index: 2; }
.pp-pin.on .pp-pin-label { max-width: 280px; }

#sun-hint { display: block; margin: 2px 0 6px 40px; }

/* night (the sun at the time of day, app.js stepSun): the text over the map turns light */
body.night .masthead, body.night .masthead .kicker, body.night .tally, body.night .tally-count, body.night .timeline { color: #e9edf3; }
body.night .masthead h1, body.night .tally-year { color: #f4f6f9; }

/* no crosshair in the middle of the map (the keyboard still opens the building there) */
.crosshair { display: none !important; }

/* Klassisk: the city as it is today, so no timeline and no legend (app.js applyLook) */
body.classic .timeline, body.classic #panel, body.classic .veil-bottom { display: none !important; }

/* The Look panel's small car: the easter egg (web/gta.js) */
.look-foot { display: flex; justify-content: flex-end; margin-top: 10px; }
.look .look-egg { width: 30px; height: 26px; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted); cursor: pointer; display: grid; place-items: center; opacity: .55; }
.look .look-egg:hover, .look .look-egg:focus-visible { opacity: 1; color: var(--accent); background: var(--line); }
.look .look-egg svg { width: 20px; height: 12px; fill: currentColor; }
/* Grand Theft Sundsvall: the map's own chrome steps aside for the game's */
body.gta .masthead, body.gta .modes, body.gta .search, body.gta .corner, body.gta #panel, body.gta .timeline,
body.gta #card, body.gta .howto, body.gta .pp, body.gta .pp-pins, body.gta .quest, body.gta .veil { display: none !important; }
.gta-hud { position: fixed; inset: 0; pointer-events: none; z-index: 50; font-family: var(--font); color: #fff; }
.gta-top { position: absolute; top: 14px; left: 16px; right: 16px; display: flex; gap: 18px; align-items: center;
  font-weight: 800; text-shadow: 0 2px 0 #000, 0 0 6px rgba(0,0,0,.6); }
.gta-title { font-size: 22px; letter-spacing: .02em; font-style: italic; color: #ffd84a; }
.gta-stars { font-size: 24px; color: #ffd84a; letter-spacing: 2px; }
.gta-stat { font-size: 16px; font-variant-numeric: tabular-nums; }
.gta-exit { margin-left: auto; pointer-events: auto; font: inherit; font-size: 14px; color: #fff; background: rgba(0,0,0,.55);
  border: 1px solid rgba(255,255,255,.4); border-radius: 8px; padding: 6px 12px; cursor: pointer; }
.gta-msg { position: absolute; left: 50%; top: 22%; transform: translateX(-50%); margin: 0; text-align: center;
  font-size: 22px; font-weight: 800; text-shadow: 0 2px 0 #000, 0 0 8px rgba(0,0,0,.7); }
.gta-msg.big b { display: block; font-size: clamp(44px, 9vw, 96px); font-style: italic; letter-spacing: .04em; }
.gta-msg.busted b { color: #4da3ff; } .gta-msg.wasted b { color: #ff4040; }
.gta-msg span, .gta-msg small { display: block; margin-top: 8px; font-size: 18px; }
.gta-msg small { font-size: 14px; opacity: .9; }
.gta-help { position: absolute; bottom: 44px; left: 50%; transform: translateX(-50%); margin: 0; font-size: 13px;
  background: rgba(0,0,0,.5); padding: 6px 12px; border-radius: 8px; white-space: nowrap; }
.gta-pad { display: none; }
@media (pointer: coarse) {
  .gta-help { display: none; }
  .gta-pad { display: grid; position: absolute; bottom: 24px; left: 16px; right: 16px; grid-template-columns: 64px 64px 1fr 64px 64px;
    grid-template-areas: "l r . d u"; gap: 10px; }
  .gta-pad button { pointer-events: auto; height: 64px; border-radius: 16px; border: 0; font-size: 26px; color: #fff;
    background: rgba(0,0,0,.45); touch-action: none; }
  .gta-pad [data-k="left"] { grid-area: l; } .gta-pad [data-k="right"] { grid-area: r; }
  .gta-pad [data-k="down"] { grid-area: d; } .gta-pad [data-k="up"] { grid-area: u; }
  .gta-top { flex-wrap: wrap; gap: 8px 14px; } .gta-title { font-size: 18px; }
}

/* Bottom left (2026-10-20): the compass, Look, About and the language in one row, above the timeline (at the very
   bottom in Klassisk, which has none); the Look panel opens upwards. Top right keeps the year and the count, in
   Tidslinje only. */
@media (min-width: 721px) and (hover: hover) {
  .buttons.dock { position: fixed; left: var(--gutter); bottom: calc(env(safe-area-inset-bottom, 0px) + 116px);
    z-index: 6; padding: 4px; border-radius: 999px; background: color-mix(in srgb, var(--panel) 70%, transparent);
    backdrop-filter: blur(6px); }
  body.classic .buttons.dock { bottom: calc(env(safe-area-inset-bottom, 0px) + 14px); }
  .buttons.dock .look { inset: auto auto calc(100% + 8px) 0; }
  .dock .north-open { width: 32px; height: 32px; border-radius: 50%; background: var(--panel); color: var(--ink); }
  .dock .north-open svg { width: 18px; height: 18px; }
  .panel { max-height: calc(100vh - 330px); }
  .buttons.dock:has(.look[open]) { z-index: 25; }
}
body.classic .corner .tally { display: none; }
body.classic .howto { bottom: calc(env(safe-area-inset-bottom, 0px) + 40px); }
body.classic .credits { bottom: calc(env(safe-area-inset-bottom, 0px) + 14px); }

/* 2026-10-20: the title on one line in one face; the search docked above the buttons, its list opening upwards; the
   credit in white on the map with no plate; the instructions a little lower */
.masthead h1 { font-size: clamp(32px, 3.4vw, 50px); white-space: nowrap; letter-spacing: -0.03em; }
.masthead .kicker { display: inline; font-size: 1em; font-weight: inherit; letter-spacing: inherit; color: inherit; margin: 0; }
.search.docked, .search.docked:focus-within { transition: none; }
.search.docked .search-list { position: absolute; left: 0; right: 0; bottom: calc(100% + 6px); margin: 0; }
.search.docked .search-msg { position: absolute; left: 0; right: 0; bottom: calc(100% + 6px); }
.credit-line { background: none; color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 0 6px rgba(0, 0, 0, .35); }
.credit-line a { text-decoration-color: rgba(255, 255, 255, .6); }
.howto { bottom: calc(env(safe-area-inset-bottom, 0px) + 140px); }
body.classic .howto { bottom: calc(env(safe-area-inset-bottom, 0px) + 34px); }

/* a bus's card (web/buses.js) */
.card .bus-line { display: inline-block; min-width: 1.6em; padding: 0 .35em; margin-right: .2em; border-radius: 6px; background: #3fae49; color: #fff; text-align: center; }
.card .bus-next-h { margin: 8px 0 2px; font-size: 12px; color: var(--muted); }
.card .bus-next { list-style: none; margin: 0 0 8px; padding: 0; }
.card .bus-next li { display: flex; justify-content: space-between; gap: 12px; padding: 3px 0; border-bottom: 1px solid var(--line); font-size: 13px; }
/* docked above the buttons at every desktop width (the 721-1100 px rule centred it) */
@media (min-width: 721px) and (hover: hover) { .search.docked { left: var(--gutter) !important; transform: none !important; } }
.card .bus-line.train { background: #1f5cc0; }
.card .bus-line:empty { display: none; }

/* Buses & trains: the info switch sits right under the show switch, no rule between */
.look-transit .est-row + .est-row { border-top: 0; margin-top: 2px; padding-top: 0; }
/* a level crossing's state on its card */
.card .lx-state b { color: var(--ink); }
.card .lx-state.closed b { color: #c8202a; }
/* Idrottsparken's match board: a TV-style score bug over the arena */
.arena-board { position: fixed; left: 0; top: 0; z-index: 6; pointer-events: none; font: 800 13px/1 var(--font, system-ui), system-ui, sans-serif; }
.arena-board .ab-bar { display: flex; align-items: stretch; height: 28px; border-radius: 6px; overflow: hidden; box-shadow: 0 6px 18px rgba(0, 0, 0, .35);
  background: #0c1424; color: #fff; letter-spacing: .06em; transform: skewX(-8deg); }
.arena-board .ab-bar > * { display: flex; align-items: center; transform: skewX(8deg); }
.arena-board .ab-t { padding: 0 10px 0 9px; position: relative; }
.arena-board .ab-t::before { content: ""; width: 4px; height: 16px; margin-right: 7px; background: var(--k); border-radius: 1px; box-shadow: 0 0 0 1px rgba(255,255,255,.25); }
.arena-board .ab-sc { background: #fff; color: #0c1424; padding: 0 10px; font-size: 16px; font-variant-numeric: tabular-nums; }
.arena-board .ab-sc i { font-style: normal; opacity: .45; padding: 0 4px; }
.arena-board .ab-clk { background: #ffc21a; color: #0c1424; padding: 0 10px; font-variant-numeric: tabular-nums; min-width: 46px; justify-content: center; }
.arena-board.playing .ab-clk::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: #d8202a; margin-right: 6px; animation: abpulse 1.2s ease-in-out infinite; }
@keyframes abpulse { 50% { opacity: .2; } }
/* Idrottsparken's card: a match card */
.card .mc { margin: -4px -2px 0; }
.card .mc-top { display: flex; justify-content: space-between; font: 700 10.5px/1 var(--font, system-ui), sans-serif; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.card .mc-top .live { color: #d8202a; }
.card .mc-top .live::before { content: "● "; animation: abpulse 1.2s ease-in-out infinite; }
.card .mc-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; background: #0c1424; color: #fff; border-radius: 12px; padding: 14px 14px; }
.card .mc-team { display: flex; flex-direction: column; align-items: center; gap: 6px; font-weight: 700; font-size: 12.5px; text-align: center; line-height: 1.15; }
.card .mc-team b { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; letter-spacing: .04em;
  background: var(--k); color: var(--k2); box-shadow: 0 0 0 2px rgba(255,255,255,.85); }
.card .mc-mid { text-align: center; }
.card .mc-score { font: 800 30px/1 var(--font, system-ui), sans-serif; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.card .mc-score i { font-style: normal; opacity: .4; padding: 0 5px; }
.card .mc-when { font: 800 15px/1.15 var(--font, system-ui), sans-serif; }
.card .mc-sub { margin-top: 6px; font-size: 11px; font-weight: 700; letter-spacing: .06em; color: #0c1424; background: #ffc21a; border-radius: 4px; padding: 3px 7px; display: inline-block; }
.card .mc-hint { margin: 10px 0 0; text-align: center; color: var(--muted); font-size: 12px; }
.card .arena-tix { display: block; text-align: center; margin-top: 10px; background: #ffc21a; color: #0c1424; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; font-size: 13px; padding: 11px 12px; border-radius: 10px; text-decoration: none; }
.card .arena-tix:hover { background: #ffcf45; }
.card .muted { color: var(--muted); font-weight: 400; }
body.gta .arena-board, body.cinema .arena-board { display: none; }
/* Look's advanced settings: an expander under the rest */
.look-adv { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 10px; }
.look-adv summary { cursor: pointer; font-weight: 600; font-size: 13px; color: var(--ink); list-style: none; display: flex; align-items: center; gap: 6px; }
.look-adv summary::-webkit-details-marker { display: none; }
.look-adv summary::before { content: ""; width: 7px; height: 7px; border: solid var(--muted); border-width: 0 2px 2px 0; transform: rotate(-45deg); transition: transform .15s; margin-right: 2px; }
.look-adv[open] summary::before { transform: rotate(45deg); }
.look-adv .look-advanced { margin-top: 8px; }
.look-advanced .est-row + .est-row { border-top: 0; }

.card.pinned .mc-top { padding-right: 34px; }
/* A home for sale: its own card (app.js saleCard) */
.card:has(> .listing) { padding: 0; overflow: hidden; width: min(360px, calc(100vw - 24px)); }
.card .listing { margin: 0; }
.card .ls-photo { position: relative; margin: 0; aspect-ratio: 3 / 2; background: #d9dee4; }
.card .ls-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.card .ls-badge { position: absolute; left: 12px; top: 12px; background: #ffc21a; color: #0c1424; font: 800 11px/1 var(--font, system-ui), sans-serif;
  letter-spacing: .1em; text-transform: uppercase; padding: 6px 9px; border-radius: 6px; box-shadow: 0 2px 8px rgba(0,0,0,.2); }
.card .ls-photo figcaption { position: absolute; right: 8px; bottom: 6px; font-size: 10.5px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.card .ls-body { padding: 14px 16px 16px; }
.card .ls-body h3 { margin: 0; font-size: 19px; line-height: 1.15; letter-spacing: -.01em; }
.card .ls-area { margin: 3px 0 0; color: var(--muted); font-size: 13px; }
.card .ls-price { margin: 10px 0 0; font: 800 24px/1 var(--font, system-ui), sans-serif; letter-spacing: -.015em; }
.card .ls-facts { display: grid; grid-template-columns: repeat(4, auto); justify-content: space-between; gap: 8px; margin: 12px 0 0; padding: 10px 0 0;
  border-top: 1px solid var(--line); }
.card .ls-facts div { min-width: 0; }
.card .ls-facts dt { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.card .ls-facts dd { margin: 2px 0 0; font-weight: 700; font-size: 14px; white-space: nowrap; }
.card .ls-lede { margin: 12px 0 0; font-size: 13.5px; line-height: 1.45; }
.card .ls-meta { margin: 6px 0 0; font-size: 12px; color: var(--muted); }
.card .ls-hint { margin: 12px 0 0; font-size: 12.5px; color: var(--muted); }
.card .ls-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 14px; }
.card .ls-btns a { display: block; text-align: center; padding: 11px 8px; border-radius: 10px; font-weight: 800; font-size: 13.5px; text-decoration: none; }
.card .ls-more { background: var(--bg); color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
.card .ls-bid { background: #0c1424; color: #fff; }
.card .ls-bid:hover { background: #1b2840; }
.card:has(> .listing) > .card-close { position: absolute; z-index: 2; background: rgba(255,255,255,.92); }
/* About: the contact button (the address appears on a click) */
.about .about-mail { border: 1px solid var(--line); background: var(--bg); color: var(--ink); border-radius: 999px; padding: 6px 14px; font: inherit; font-weight: 600; cursor: pointer; }
.about .about-mail:hover { border-color: var(--accent); color: var(--accent); }
/* the bus, train and crossing cards: room round their content */
.card.tcard { padding: 14px 16px 12px; }
.card.tcard > h3 { margin-top: 0; }
.card.tcard.pinned > h3 { padding-right: 30px; }

.card .ls-facts dd { text-align: left; }
.card .ls-btns a { white-space: nowrap; font-size: 13px; }

/* Air quality at a station: the status first, three values, the source */
.card.tcard:has(> .aq) { width: min(300px, calc(100vw - 24px)); padding: 14px 16px 12px; }
.card .aq-head h3 { margin: 0; font-size: 16px; line-height: 1.2; }
.card .aq-head p { margin: 2px 0 0; font: 700 10.5px/1.2 var(--font, system-ui), sans-serif; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.card .aq-status { display: flex; align-items: center; gap: 9px; margin: 12px 0 0; font: 800 24px/1.1 var(--font, system-ui), sans-serif; letter-spacing: -.015em; color: var(--ink); }
.card .aq-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--c); box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 22%, transparent); flex: none; }
.card .aq-why { margin: 5px 0 0; font-size: 13px; line-height: 1.4; color: var(--muted); }
.card .aq-row { display: grid; grid-template-columns: repeat(3, 1fr); margin: 12px 0 0; padding: 10px 0 0; border-top: 1px solid var(--line); }
.card .aq-m { display: flex; flex-direction: column; padding: 0 8px; min-width: 0; }
.card .aq-m + .aq-m { border-left: 1px solid var(--line); }
.card .aq-m:first-child { padding-left: 0; }
.card .aq-m b { font: 800 20px/1 var(--font, system-ui), sans-serif; font-variant-numeric: tabular-nums; color: var(--ink); }
.card .aq-m.lead b { color: var(--c); }
.card .aq-m span { margin-top: 4px; font-size: 11.5px; line-height: 1.2; color: var(--ink); }
.card .aq-m i { font-style: normal; font-size: 10.5px; color: var(--muted); }
.card .aq-unit { margin: 8px 0 0; font-size: 10.5px; color: var(--muted); }
.card .aq-src { margin: 4px 0 0; font-size: 10.5px; color: var(--muted); }

/* Look's switches: a live state as a quiet line under the switch, a description behind an (i) */
.look .est-row { display: flex; flex-wrap: wrap; align-items: center; column-gap: 6px; }
.look .est-row .switch { flex: 0 1 auto; }
.look .sw-sub { flex-basis: 100%; margin: 3px 0 0 42px; font-size: 11.5px; line-height: 1.35; color: var(--muted); }
.look .sw-tip { position: relative; display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; flex: none;
  border: 1px solid var(--line); color: var(--muted); font: 700 11px/1 Georgia, serif; font-style: italic; cursor: help; }
.look .sw-tip:hover, .look .sw-tip:focus-visible { color: var(--ink); border-color: var(--muted); outline: none; }
.look .sw-tip-body { position: absolute; z-index: 5; right: -6px; bottom: calc(100% + 8px); width: 220px; padding: 9px 11px; border-radius: 10px;
  background: #0c1424; color: #fff; font: 400 12px/1.4 var(--font, system-ui), sans-serif; font-style: normal; text-align: left;
  box-shadow: 0 8px 22px rgba(0,0,0,.25); opacity: 0; transform: translateY(4px); pointer-events: none; transition: opacity .15s, transform .15s; }
.look .sw-tip:hover .sw-tip-body, .look .sw-tip:focus .sw-tip-body { opacity: 1; transform: none; }

/* the story walks' covers: the title large over the picture */
.s-cover { position: relative; display: block; }
.s-cover::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(8,10,16,.82) 0%, rgba(8,10,16,.35) 42%, rgba(8,10,16,0) 70%); }
.s-cover-title { position: absolute; z-index: 1; left: 14px; right: 14px; bottom: 12px; color: #fff; font: 800 clamp(20px, 2.1vw, 27px)/1.05 var(--font, system-ui), sans-serif;
  letter-spacing: -.02em; text-shadow: 0 2px 12px rgba(0,0,0,.45); text-wrap: balance; }
.s-card:hover .s-cover img { filter: saturate(1.08) brightness(1.04); }
@media (max-width: 720px) { .s-cover { width: 42%; flex: none; } .s-cover img { width: 100% !important; height: 100%; } .s-cover-title { font-size: 17px; left: 10px; bottom: 9px; } }
/* Desktop: the legend on the right, straight under the year and the count */
@media (min-width: 721px) {
  .panel { left: auto; right: var(--gutter); top: calc(env(safe-area-inset-top, 0px) + var(--gutter) + 104px); width: min(320px, calc(100vw - 2 * var(--gutter))); max-height: calc(100vh - 360px); }
}

/* the time under the title: white, left, the size of the title */
.masthead-clock { margin: 2px 0 0; font-size: clamp(32px, 3.4vw, 50px); font-weight: 800; letter-spacing: -0.03em; line-height: .95; color: #fff;
  font-variant-numeric: tabular-nums; display: flex; align-items: center; gap: .32em; }
.masthead-clock .mc-wx { display: inline-flex; align-items: center; gap: .14em; }
.masthead-clock .mc-wx[hidden] { display: none; }
.masthead-clock .mc-ic svg { width: .82em; height: .82em; display: block; }
@media (max-width: 720px) { .masthead-clock { font-size: 32px; } .corner { top: calc(env(safe-area-inset-top, 0px) + 96px); } }

/* ?light=dev: the light's developer panel */
.light-dev { position: fixed; z-index: 50; right: 12px; top: 12px; width: 260px; max-height: calc(100vh - 24px); overflow: auto; padding: 12px 14px;
  background: rgba(12,20,36,.92); color: #fff; border-radius: 12px; font: 12px/1.3 system-ui, sans-serif; display: grid; gap: 6px; }
.light-dev label { display: grid; grid-template-columns: 1fr auto; gap: 2px 8px; align-items: center; }
.light-dev input[type=range] { grid-column: 1 / -1; width: 100%; }
.light-dev .ld-tg label, .light-dev .ld-t { display: flex; gap: 6px; }
.light-dev .ld-btns { display: flex; gap: 6px; } .light-dev button { flex: 1; padding: 6px; border-radius: 6px; border: 0; cursor: pointer; }

/* Desktop: the mode tabs top right; the legend panel under them, headed by the year and the count */
@media (min-width: 721px) {
  .modes { left: auto; right: var(--gutter); transform: none; }
  .panel { top: calc(env(safe-area-inset-top, 0px) + var(--gutter) + 62px); }
  .panel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
  .panel-head .tally { position: static; text-align: left; margin: 0; }
  .panel-head .tally-year { font-size: 30px; line-height: 1; }
  .panel-head .tally-count { display: block; margin-top: 3px; color: var(--muted); }
  .panel-head .sheet-handle { display: inline-flex; width: auto; margin: 2px 0 0; padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
    background: transparent; font-size: 12px; font-weight: 600; color: var(--ink); cursor: pointer; }
  .panel-head .sheet-handle::after { display: none; }
  .panel.collapsed .panel-head { margin-bottom: 0; }
  .corner .tally { display: none; }
}

/* ?lab: the render-lab's panel and divider */
body.lab .masthead, body.lab .modes, body.lab #panel, body.lab .timeline, body.lab .howto { display: none !important; }
.lab-ui { position: fixed; z-index: 40; left: 12px; top: 12px; width: 300px; padding: 12px 14px; border-radius: 14px; background: rgba(12,20,36,.9); color: #fff;
  font: 13px/1.35 system-ui, sans-serif; display: grid; gap: 8px; box-shadow: 0 10px 30px rgba(0,0,0,.3); }
.lab-ui .lab-sub { color: #a9b4c4; font-size: 12px; margin-top: -6px; }
.lab-ui .lab-row { display: flex; flex-wrap: wrap; gap: 6px; }
.lab-ui button { padding: 6px 10px; border-radius: 999px; border: 1px solid rgba(255,255,255,.25); background: transparent; color: #fff; font: inherit; font-size: 12px; cursor: pointer; }
.lab-ui button[aria-pressed="true"] { background: #ffc21a; color: #0c1424; border-color: #ffc21a; font-weight: 700; }
.lab-ui pre { margin: 0; font: 11.5px/1.45 ui-monospace, monospace; color: #dfe6ef; white-space: pre-wrap; }
.lab-split { position: fixed; z-index: 30; top: 0; bottom: 0; width: 0; cursor: ew-resize; }
.lab-split i { position: absolute; top: 0; bottom: 0; left: -1px; width: 2px; background: rgba(255,255,255,.9); box-shadow: 0 0 8px rgba(0,0,0,.4); }
.lab-split::before { content: ""; position: absolute; top: 0; bottom: 0; left: -14px; width: 28px; }
.lab-split span { position: absolute; top: 50%; transform: translateY(-50%); padding: 4px 9px; border-radius: 999px; background: rgba(12,20,36,.8); color: #fff; font: 700 11px system-ui; white-space: nowrap; }
.lab-split span:first-child { right: 10px; } .lab-split span:last-of-type { left: 10px; }

@media (min-width: 721px) {
  .panel { padding-top: 14px; }
  .panel.collapsed { width: min(320px, calc(100vw - 2 * var(--gutter))); padding: 12px 16px; overflow: visible; border-radius: 10px; }
  .panel-head .sheet-handle, .panel.collapsed .panel-head .sheet-handle { position: static; width: auto; height: auto; margin: 2px 0 0; padding: 4px 10px; background: transparent; }
}
body.lab .veil { display: none; }

/* the new look: the sky dome shows over the top of the page; the bottom veil takes the haze's colour */
body.newlook .veil-top { display: none; }

/* Tidslinje: the hint over the timeline's handle */
.time-hint { position: absolute; z-index: 60; right: 50%; bottom: calc(100% + 18px); white-space: nowrap; pointer-events: none; padding: 14px 22px; border-radius: 999px;
  background: #0c1424; color: #fff; font: 800 22px/1 var(--font, system-ui), sans-serif; box-shadow: 0 6px 16px rgba(0,0,0,.22); transform: translateX(14px);
  animation: timehint 1.6s ease-in-out infinite; }
.time-hint::after { content: ""; position: absolute; right: 8px; top: 100%; border: 6px solid transparent; border-top-color: #0c1424; }
.time-hint::before { content: "← "; }
@keyframes timehint { 50% { transform: translate(6px, -2px); } }

/* the timeline (and its hint) over the legend panel */
.timeline { z-index: 22; }
.timeline .grip-to { z-index: 23; }
.time-hint::after { right: 14px; border-width: 9px; }

/* the listing card's "Nearby" list (app.js nearHtml) */
.ls-near { margin: 10px 0 4px; }
.ls-near h4 { margin: 0 0 6px; font-size: 12px; letter-spacing: .04em; text-transform: uppercase; color: var(--muted, #5b6573); }
.ls-near ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.ls-near li { display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 8px; font-size: 13px; line-height: 1.25;
  padding: 4px 8px 4px 4px; border-radius: 10px; background: color-mix(in srgb, var(--c) 10%, transparent); }
.ls-near .ln-i { width: 26px; height: 26px; border-radius: 50%; background: var(--c); display: grid; place-items: center; font-size: 14px; }
.ls-near .ln-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ls-near .ln-n b { color: var(--c); font-weight: 700; margin-right: 3px; }
.ls-near .ln-m { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }

/* /heja: a post from Heja Sundsvall's Instagram (app.js hejaCard) */
.igpost .ig-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px; }
.igpost .ig-av { width: 36px; height: 36px; border-radius: 11px; display: grid; place-items: center; color: #fff; flex: none;
  background: linear-gradient(45deg, #feda75, #fa7e1e 35%, #d62976 65%, #4f5bd5); }
.igpost .ig-av svg { width: 22px; height: 22px; }
.igpost .ig-name { font-weight: 800; color: inherit; text-decoration: none; }
.igpost .ig-loc { margin: 1px 0 0; font-size: 12px; color: var(--muted, #5b6573); }
.card .igpost .ls-photo { aspect-ratio: 1 / 1; }
.card .igpost .ls-photo img { object-position: 50% 35%; }
.igpost .ig-text { margin: 6px 0; font-size: 13.5px; line-height: 1.45; }
.igpost .ig-src { margin: 10px 0 4px; font-size: 12px; color: var(--muted, #5b6573); }
.igpost .ig-src a { color: #d62976; font-weight: 700; }
.igpost .ig-btn { display: inline-flex; align-items: center; gap: 6px; background: linear-gradient(45deg, #fa7e1e, #d62976 55%, #4f5bd5); color: #fff; border: 0; }
.igpost .ig-btn svg { width: 16px; height: 16px; }

/* A listing's or a news post's card (pinned) over the map's chrome; on a phone a tall sheet that scrolls as one,
   its photo kept low, the close button always in reach */
.card.pinned:has(.listing) { z-index: 30; }
@media (max-width: 720px) {
  .card.pinned:has(.listing) { top: calc(env(safe-area-inset-top, 0px) + 60px) !important; bottom: 0; max-height: none !important;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch; touch-action: pan-y; }
  .card.pinned:has(.listing) .card-close { position: sticky; top: 8px; float: right; margin: 8px 8px -38px 0; z-index: 2;
    background: rgba(255,255,255,.92); box-shadow: 0 1px 6px rgba(0,0,0,.2); }
  .card.pinned .listing .ls-photo, .card.pinned .igpost .ls-photo { aspect-ratio: auto; height: 34vh; }
  .card.pinned .listing .ls-body { padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 28px); }
  .card.pinned .ig-text { font-size: 15px; }
}

/* a train's card: on time, late or cancelled at Sundsvall C (app.js transitHtml, Trafikverket) */
.tr-route { font-weight: 600; margin: 2px 0; }
.tr-when { margin: 4px 0; }
.tr-st { display: inline-block; padding: 1px 8px; border-radius: 999px; font-weight: 700; font-size: 12px; margin-right: 4px; }
.tr-st.ok { background: #dff3e4; color: #17693a; }
.tr-st.late { background: #fde7c8; color: #9a4a00; }
.tr-st.bad { background: #fbd5d5; color: #a1161c; }
.tr-notes { margin: 4px 0; padding-left: 18px; color: #9a4a00; }
/* Väginformation's cards (web/livelayers.js makeRoadInfo) */
.ri { padding: 12px 16px 10px; }
.ri h3 { margin: 0 30px 2px 0; font-size: 16px; }
.ri .muted { color: var(--muted, #5b6573); margin: 2px 0; }
.ri-cam { margin: 8px 0 4px; }
.ri-cam img { display: block; width: 100%; border-radius: 8px; background: #d9dee4; aspect-ratio: 4 / 3; object-fit: cover; }
.ri-temps { display: flex; gap: 18px; margin: 8px 0; }
.ri-temps b { font-size: 26px; display: block; line-height: 1; }
.ri-temps span { font-size: 12px; color: var(--muted, #5b6573); }
.ri-sit { border-top: 1px solid var(--line, #e4e6e8); padding: 6px 0; }
.ri-sit:first-of-type { border-top: 0; }
.ri-sit p { margin: 2px 0; }
.ri-sev { display: inline-block; font-size: 11px; padding: 0 6px; border-radius: 999px; background: #fde7c8; color: #9a4a00; }

/* Sundsvall C's board (app.js stationHtml): a departure board, the late times in amber, the cancelled in red */
.sboard { padding: 12px 16px 10px; }
.sboard h3 { margin: 0 30px 0 0; font-size: 18px; }
.sboard h4 { margin: 10px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted, #5b6573); }
.sb { width: 100%; border-collapse: collapse; font-size: 13px; background: #14202e; color: #f2f4f7; border-radius: 8px; overflow: hidden; }
.sb th { text-align: left; font-weight: 600; font-size: 11px; color: #9fb0c3; padding: 5px 6px; }
.sb td { padding: 5px 6px; border-top: 1px solid rgba(255,255,255,.08); vertical-align: top; }
.sb .sb-t { font-variant-numeric: tabular-nums; font-weight: 700; color: #ffd84a; }
.sb .sb-d small { display: block; color: #ffb35c; font-size: 11px; }
.sb .sb-n { color: #c6d2df; white-space: nowrap; } .sb .sb-n span { opacity: .7; }
.sb .sb-tr { text-align: center; font-weight: 700; }
.sb .sb-late { color: #ffb35c; } .sb .sb-bad { color: #ff6b6b; } .sb .sb-gone { color: #8a9bb0; font-size: 11px; }
.sb tr.gone td { opacity: .6; }

/* the board's preview (hover): time, status, where, track; one line each, the place cut short with an ellipsis */
.sb.sb-mini { table-layout: fixed; }
.sb.sb-mini th:nth-child(1), .sb.sb-mini td:nth-child(1) { width: 48px; }
.sb.sb-mini th:nth-child(2), .sb.sb-mini td:nth-child(2) { width: 66px; }
.sb.sb-mini th:nth-child(4), .sb.sb-mini td:nth-child(4) { width: 40px; }
.sb.sb-mini td { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card:has(.sboard) { width: 360px; }
.card.pinned:has(.sboard) { width: 440px; }
.sb .sb-d { white-space: nowrap; }

/* the first visit's card on moving around (app.js navHelp) */
.navhelp { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; background: rgba(12, 20, 36, .42); backdrop-filter: blur(2px); padding: 16px; }
.nh-card { background: var(--panel, #fff); color: var(--ink, #14202e); border-radius: 18px; max-width: 760px; width: 100%; padding: 26px 28px 22px;
  box-shadow: 0 20px 60px rgba(12, 20, 36, .35); max-height: calc(100vh - 32px); overflow-y: auto; }
.nh-card h2 { margin: 0 0 4px; font-size: 26px; letter-spacing: -.01em; }
.nh-lede { margin: 0 0 8px; color: var(--muted, #5b6573); font-size: 15px; }
.nh-tip { margin: 0 0 16px; padding: 8px 12px; border-radius: 10px; background: rgba(194, 65, 12, 0.08); font-size: 14px; line-height: 1.4; }
.nh-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.nh-col { border: 1px solid var(--line, #e2e5e8); border-radius: 12px; padding: 12px 14px; }
.nh-col.own { border-color: var(--ink, #14202e); box-shadow: 0 0 0 1px var(--ink, #14202e) inset; }
.nh-col h3 { margin: 0 0 8px; font-size: 15px; } .nh-col h3 span { font-size: 11px; font-weight: 600; background: #ffd84a; color: #14202e; border-radius: 999px; padding: 1px 7px; margin-left: 4px; vertical-align: 2px; }
.nh-col dl { margin: 0; display: grid; gap: 7px; } .nh-col dt { font-weight: 700; font-size: 13px; } .nh-col dd { margin: 1px 0 0; font-size: 13px; color: var(--muted, #5b6573); }
.nh-home { margin: 16px 0 4px; font-size: 15px; } .nh-tip { margin: 0 0 16px; font-size: 13px; color: var(--muted, #5b6573); }
.nh-go { border: 0; border-radius: 999px; background: var(--ink, #14202e); color: #fff; font: inherit; font-weight: 700; padding: 11px 22px; cursor: pointer; }
@media (max-width: 720px) { .nh-cols { grid-template-columns: 1fr; } .nh-card { padding: 20px 18px; } .nh-card h2 { font-size: 22px; } }

/* Gustav Adolfs kyrka's card (app.js gaCard) */
.ga { padding: 14px 16px 12px; }
.ga-head { border-left: 5px solid #a8553f; padding-left: 10px; margin-bottom: 8px; }
.ga-head h3 { margin: 0; font-size: 19px; } .ga-head p { margin: 2px 0 0; color: var(--muted, #5b6573); font-size: 12.5px; }
.ga h4 { margin: 10px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted, #5b6573); }
.ga-list { list-style: none; margin: 0 0 8px; padding: 0; display: grid; gap: 4px; font-size: 13px; } .ga-list b { color: #a8553f; margin-right: 4px; }
.ga-clock { font-size: 12.5px; color: var(--muted, #5b6573); }
.ga .ls-bid { display: inline-block; margin-top: 6px; }

/* Aircraft overhead (app.js stepPlanes, 2026-10-22): an arrow at the top nudging upwards, the bird's-eye card */
.plane-nudge { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; gap: 10px;
  padding: 8px 12px 8px 10px; border: 0; border-radius: 999px; background: rgba(18, 26, 33, 0.88); color: #fff; font: inherit; cursor: pointer;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.28); backdrop-filter: blur(6px); animation: pn-in 0.5s ease-out; }
.plane-nudge[hidden] { display: none; }
.plane-nudge .pn-arrow { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: #fff; color: #121a21; animation: pn-nudge 1.8s ease-in-out infinite; }
.plane-nudge .pn-text { display: grid; text-align: left; line-height: 1.2; }
.plane-nudge .pn-text b { font-size: 15px; }
.plane-nudge .pn-text small { font-size: 12px; opacity: 0.8; }
.plane-nudge .pn-x { margin-left: 4px; padding: 2px 6px; font-size: 18px; line-height: 1; opacity: 0.6; }
.plane-nudge .pn-x:hover { opacity: 1; }
.plane-nudge:hover .pn-arrow { animation-duration: 0.9s; }
@keyframes pn-nudge { 0%, 55%, 100% { transform: translateY(0); } 25% { transform: translateY(-5px); } 40% { transform: translateY(1px); } }
@keyframes pn-in { from { opacity: 0; transform: translate(-50%, -12px); } to { opacity: 1; transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .plane-nudge, .plane-nudge .pn-arrow { animation: none; } }
.plane-tag { position: fixed; left: 0; top: 0; z-index: 30; pointer-events: none; padding: 3px 8px; border-radius: 6px; background: rgba(18, 26, 33, 0.85);
  color: #fff; font-size: 13px; font-weight: 600; white-space: nowrap; }
.plane-tag[hidden], .plane-card[hidden] { display: none; }
.plane-card { position: fixed; top: 84px; right: 18px; z-index: 35; width: 300px; padding: 16px 18px; border-radius: 14px; background: var(--bg, #fff); color: var(--ink);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22); }
.plane-card .pc-kicker { margin: 0 0 2px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.65; }
.plane-card h3 { margin: 0; font-size: 22px; }
.plane-card h3 small { font-size: 14px; font-weight: 500; opacity: 0.7; }
.plane-card .pc-route { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 12px 0; font-size: 15px; font-weight: 600; }
.plane-card .pc-arrow { color: var(--accent); }
.plane-card .pc-none { font-weight: 400; opacity: 0.7; }
.plane-card dl { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; margin: 0 0 14px; }
.plane-card dl div:last-child { grid-column: 1 / -1; }
.plane-card dt { font-size: 12px; opacity: 0.6; }
.plane-card dd { margin: 0; font-size: 15px; font-weight: 600; }
.plane-card .pc-back { width: 100%; padding: 10px; border: 0; border-radius: 10px; background: var(--ink); color: #fff; font: inherit; font-weight: 600; cursor: pointer; }
.plane-card .pc-src { margin: 10px 0 0; font-size: 11px; opacity: 0.55; }
@media (max-width: 720px) {
  .plane-nudge { top: 10px; max-width: calc(100vw - 24px); }
  .plane-nudge .pn-text b { font-size: 14px; }
  .plane-card { top: auto; bottom: 12px; left: 12px; right: 12px; width: auto; }
}
