:root {
  --bg: #05070c;
  --panel-bg: rgba(10, 14, 22, 0.55);
  --panel-border: rgba(255, 255, 255, 0.08);
  --text: #d7dde6;
  --text-dim: #8891a0;
  --tier-1: #4a4f57;
  --tier-2: #5b7a94;
  --tier-3: #e0c34a;
  --tier-4: #e8934a;
  --tier-5: #e0473f;
  /* Tiers 1 and 2 are too dark to read as small text; these are their
     brighter stand-ins for words. */
  --tier-1-text: #8891a0;
  --tier-2-text: #8fb0cc;
  --pin-accent: #5ad1e0;
  --accent: #5ad1e0;
  --briefing-w: 340px;
  --radius: 4px;
  /* The bar across the top of the window. chrome.js and the desktop app's
     main.js carry the same colour and height. */
  --bar-h: 48px;
  --bar-bg: #0a0e16;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

/* --- the two readers ----------------------------------------------------
   Professional is the look above: near-black, cyan, square corners, small
   capitals and tags. Everyday is warmer and rounder: an indigo sky, a lilac
   accent, sentence case and larger type, so the two can be told apart before
   a word is read. The scene's own background is set to match in main.js. */
body[data-mode="everyday"] {
  --bg: #0d0b2b;
  --panel-bg: rgba(27, 22, 72, 0.66);
  --panel-border: rgba(196, 184, 255, 0.2);
  --text: #ece9ff;
  --text-dim: #a9a3cf;
  --accent: #c0b0ff;
  --radius: 14px;
  --bar-bg: #15123f;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  overflow: hidden;
}

#scene-container {
  position: fixed;
  inset: 0;
}

#scene-container canvas {
  display: block;
}

.hud {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
}

/* Only the boxes that actually take input opt back in to pointer events.
   This used to be `.hud > *`, which handed `auto` to `.topbar` — a transparent
   full-width strip roughly 42px tall spanning the whole window. It is invisible
   but it swallowed every click along the top of the scene, so a planet drifting
   through that band could not be selected at all. Targeting the real controls
   instead leaves the gaps between them transparent to the canvas underneath. */
.brand,
.mode-switch,
.filter-bar,
.refresh-btn,
.status-line,
.legend {
  pointer-events: auto;
}

/* The panel and its backdrop take input only while actually open. Keying this
   on the class rather than on visibility matters because both fade out over
   ~180ms: for that whole window a closed backdrop would still be covering the
   scene, and a click aimed at a planet immediately after dismissing an article
   would be swallowed by it. */
.info-panel.open,
.info-backdrop.open,
body.briefing-open .briefing {
  pointer-events: auto;
}

/* Keyboard focus is always visible. The browser default is a thin dark ring
   that disappears against this background. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The panel takes focus itself when it opens so its title is announced; it is
   a container, not a control, and gets no ring. */
.info-panel:focus {
  outline: none;
}

.topbar {
  position: absolute;
  top: 16px;
  left: 16px;
  right: 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 16px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.brand h1 {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.06em;
  margin: 0;
  text-transform: uppercase;
}

.brand .nav-link {
  font-size: 12px;
  color: var(--text-dim);
  text-decoration: none;
  border-left: 1px solid var(--panel-border);
  padding-left: 10px;
}

.brand .nav-link:hover {
  color: var(--accent);
}

.brand .nav-button {
  appearance: none;
  background: none;
  border: 0;
  border-left: 1px solid var(--panel-border);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.brand .nav-button[aria-expanded="true"] {
  color: var(--accent);
}

.mode-switch {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
  padding: 6px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.filter-bar {
  display: flex;
  gap: 6px;
  padding: 6px;
  /* Eleven filters do not fit every window. The bar scrolls sideways inside
     itself and the page never does. */
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* On anything wider than a phone the name, the places to go and the reader
   switch stay on one line. (The filters and the refresh button are placed
   beneath them: see "the top bar as the window's title bar".) */
@media (min-width: 768px) {
  .topbar {
    flex-wrap: nowrap;
  }

  .brand {
    flex: 0 0 auto;
  }
}

.mode-switch button,
.filter-bar button {
  appearance: none;
  flex: 0 0 auto;
  white-space: nowrap;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-dim);
  font-size: 12px;
  letter-spacing: 0.03em;
  padding: 6px 12px;
  border-radius: 3px;
  cursor: pointer;
  font-family: inherit;
  text-transform: uppercase;
}

.mode-switch button:hover,
.filter-bar button:hover {
  color: var(--text);
  border-color: var(--panel-border);
}

.mode-switch button.active,
.filter-bar button.active {
  color: var(--bg);
  background: var(--accent);
}

.refresh-btn {
  appearance: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--text-dim);
  cursor: pointer;
}

.refresh-btn:hover:not(:disabled) {
  color: var(--text);
  border-color: var(--accent);
}

.refresh-btn:disabled {
  cursor: default;
  opacity: 0.6;
}

.refresh-btn svg {
  transition: transform 240ms ease-out;
}

.refresh-btn.spinning svg {
  animation: refresh-spin 900ms linear infinite;
}

@keyframes refresh-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.status-line {
  position: absolute;
  bottom: 16px;
  left: 16px;
  font-size: 11px;
  color: var(--text-dim);
  padding: 6px 10px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* Dims the scene behind an open article and acts as the click-outside target.
 *
 * `visibility` is switched, not transitioned. Transitioning it in both
 * directions leaves the element computing as hidden for the first frame after
 * opening, and a hidden element is not hit-testable: a click arriving in that
 * window falls straight through the backdrop to the canvas and selects another
 * planet instead of dismissing the article. So visibility flips to visible with
 * no delay on open, and its return to hidden is delayed until the fade has
 * finished on close. */
.info-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(3, 5, 9, 0.66);
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms ease-out, visibility 0s linear 180ms;
}

.info-backdrop.open {
  opacity: 1;
  visibility: visible;
  transition: opacity 180ms ease-out, visibility 0s;
}

/* Centred on the viewport rather than pinned to a corner. On a large monitor a
   top-right panel lands a long way from where the eye already is — the planet
   that was just clicked, near the middle of the screen. */
.info-panel {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 460px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  background: rgba(10, 14, 22, 0.86);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.55);
  padding: 18px;
  opacity: 0;
  /* Hidden rather than merely transparent, so a closed panel is out of the tab
     order and its buttons cannot be reached by keyboard. Same visibility
     switching as the backdrop above — see the note there. */
  visibility: hidden;
  transform: translate(-50%, -50%) scale(0.97);
  transition: opacity 160ms ease-out, transform 160ms ease-out,
    visibility 0s linear 160ms;
}

.info-panel.open {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, -50%) scale(1);
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s;
}

@media (prefers-reduced-motion: reduce) {
  .info-panel,
  .info-backdrop {
    transition: none;
  }

  .info-panel,
  .info-panel.open {
    transform: translate(-50%, -50%);
  }
}

.info-panel .close-btn {
  position: absolute;
  top: 10px;
  right: 12px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 16px;
  cursor: pointer;
  line-height: 1;
}

.info-panel .close-btn:hover {
  color: var(--text);
}

.info-panel .source-line {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.info-panel h2 {
  font-size: 16px;
  line-height: 1.4;
  margin: 0 0 10px;
  padding-right: 20px;
}

.info-panel .categories {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 12px;
}

.badge {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 8px;
  border-radius: 3px;
  border: 1px solid var(--panel-border);
  color: var(--text-dim);
}

.badge.corroborated {
  border-color: rgba(90, 209, 224, 0.4);
  color: var(--accent);
}

.badge.severity {
  font-weight: 600;
  border-color: currentColor;
}

.badge.severity.tier-5 { color: var(--tier-5); }
.badge.severity.tier-4 { color: var(--tier-4); }
.badge.severity.tier-3 { color: var(--tier-3); }
.badge.severity.tier-2 { color: var(--tier-2-text); }
.badge.severity.tier-1 { color: var(--text-dim); }

/* The parts of a story: what it means, how far it reaches, what to do. */
.info-part {
  margin-bottom: 16px;
}

.info-part[hidden] {
  display: none;
}

.info-part h3 {
  margin: 0 0 6px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

.info-part p,
.info-part li {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--text);
}

.info-part ul {
  margin: 0;
  padding-left: 18px;
}

.info-part li + li,
.info-part p + p {
  margin-top: 5px;
}

/* A professional's tellings are denser and set like a report. */
.info-panel[data-mode="professional"] .info-part p,
.info-panel[data-mode="professional"] .info-part li {
  font-size: 13px;
}

.info-part .ref {
  display: inline-block;
  margin: 0 6px 6px 0;
  padding: 4px 9px;
  border: 1px solid rgba(90, 209, 224, 0.4);
  border-radius: 3px;
  font: 12px/1.3 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--accent);
  text-decoration: none;
}

.info-part .ref:hover {
  background: rgba(90, 209, 224, 0.12);
}

.info-panel .impact-line {
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--text);
  margin: 0;
  padding: 8px 10px;
  border-left: 2px solid var(--accent);
  background: rgba(255, 255, 255, 0.03);
}

.info-panel .impact-line.estimated {
  color: var(--text-dim);
  border-left-color: var(--panel-border);
  font-style: italic;
}

/* --- proximity labels --------------------------------------------------- */

.label-layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 5;
}

.planet-label {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 5px 9px;
  border-radius: 3px;
  border: 1px solid var(--panel-border);
  border-left-width: 2px;
  background: rgba(6, 9, 15, 0.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 420ms ease-out;
  will-change: transform, opacity;
}

/* The story's own headline, on at most two lines. */
.label-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  max-width: 220px;
  margin-bottom: 1px;
  overflow: hidden;
  white-space: normal;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
}

.label-headline,
.label-fact {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The story being pointed at, in the scene or in the briefing list. */
.planet-label.pointed {
  z-index: 2;
  border-color: var(--accent);
  background: rgba(6, 9, 15, 0.92);
}

/* The short form: the headline alone, on one line. */
.planet-label.compact {
  padding: 3px 7px;
}

.planet-label.compact .label-headline,
.planet-label.compact .label-fact {
  display: none;
}

.planet-label.compact .label-name {
  -webkit-line-clamp: 1;
  max-width: 180px;
  margin-bottom: 0;
  font-size: 11px;
  font-weight: 500;
}

.label-headline {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  line-height: 1.2;
}

.label-fact {
  font-size: 11px;
  letter-spacing: 0.01em;
  color: var(--text);
  line-height: 1.3;
}

.planet-label.tier-5 { border-left-color: var(--tier-5); }
.planet-label.tier-5 .label-headline { color: var(--tier-5); }
.planet-label.tier-4 { border-left-color: var(--tier-4); }
.planet-label.tier-4 .label-headline { color: var(--tier-4); }
.planet-label.tier-3 { border-left-color: var(--tier-3); }
.planet-label.tier-3 .label-headline { color: var(--tier-3); }
.planet-label.tier-2 { border-left-color: var(--tier-2); }
.planet-label.tier-2 .label-headline { color: var(--tier-2-text); }
.planet-label.tier-1 { border-left-color: var(--tier-1); }
.planet-label.tier-1 .label-headline { color: var(--text-dim); }

/* --- legend ------------------------------------------------------------- */

.legend {
  position: absolute;
  bottom: 16px;
  right: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 12px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 10px;
  color: var(--text-dim);
}

.legend-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.legend-title {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text);
}

.legend-scale {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.legend-scale li {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}

.legend-scale b {
  font-weight: 400;
}

.legend-dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
}

.legend-dot.tier-1 { background: var(--tier-1); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25); }
.legend-dot.tier-2 { background: var(--tier-2); }
.legend-dot.tier-3 { background: var(--tier-3); }
.legend-dot.tier-4 { background: var(--tier-4); }
.legend-dot.tier-5 { background: var(--tier-5); }

.legend-sizes i {
  border-radius: 50%;
  background: var(--text-dim);
}

.legend-sizes .size-1 { width: 5px; height: 5px; }
.legend-sizes .size-2 { width: 10px; height: 10px; }
.legend-sizes .size-3 { width: 16px; height: 16px; }

.legend-help {
  align-self: flex-start;
  padding: 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: 11px;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

/* Words meant for one reader only. */
body[data-mode="professional"] .for-everyday,
body:not([data-mode="professional"]) .for-professional {
  display: none;
}

@media (max-width: 767px) {
  .legend { display: none; }
  .planet-label { padding: 4px 7px; }
  .label-fact { font-size: 10px; }

  .label-name {
    max-width: 170px;
    font-size: 11px;
  }

  .label-headline,
  .label-fact {
    max-width: 170px;
  }

  .topbar {
    gap: 8px;
  }

  /* Three rows on a phone: the name with the refresh button beside it, then
     the reader switch, then the filters. */
  .refresh-btn {
    order: 1;
    margin-left: auto;
  }

  .mode-switch {
    order: 2;
    width: 100%;
  }

  .mode-switch button {
    flex: 1 1 0;
  }

  .filter-bar {
    order: 3;
  }

  /* The category buttons do not fit a phone width; let them scroll sideways
     rather than running off the edge where the last ones are unreachable. */
  .filter-bar {
    width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .filter-bar::-webkit-scrollbar {
    display: none;
  }

  .filter-bar button {
    flex: 0 0 auto;
    padding: 6px 10px;
  }

  /* A phone keeps the bottom-sheet treatment: centring a panel vertically on a
     small screen buries it behind the thumb and leaves the scene invisible
     above and below it. The backdrop still applies. */
  .info-panel {
    top: auto;
    bottom: 12px;
    left: 12px;
    right: 12px;
    width: auto;
    max-width: none;
    max-height: 62vh;
    transform: translateY(14px);
  }

  .info-panel.open {
    transform: translateY(0);
  }
}

.info-panel .summary {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-dim);
}

.info-panel .actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.info-panel .actions a,
.info-panel .actions button {
  font-family: inherit;
  font-size: 12px;
  letter-spacing: 0.02em;
  padding: 8px 12px;
  border-radius: 3px;
  border: 1px solid var(--panel-border);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  text-transform: uppercase;
}

.info-panel .actions a:hover,
.info-panel .actions button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.info-panel .actions button.active {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}

.loading-msg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* --- briefing list ------------------------------------------------------ */

.briefing {
  position: absolute;
  top: 70px;
  left: 16px;
  bottom: 16px;
  width: var(--briefing-w);
  max-width: calc(100vw - 32px);
  display: flex;
  flex-direction: column;
  background: rgba(10, 14, 22, 0.84);
  border: 1px solid var(--panel-border);
  border-radius: 4px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  opacity: 0;
  /* Hidden, not just transparent, so a closed list is out of the tab order. */
  visibility: hidden;
  transform: translateX(-10px);
  transition: opacity 160ms ease-out, transform 160ms ease-out,
    visibility 0s linear 160ms;
}

body.briefing-open .briefing {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s;
}

/* Where there is room, the list gets a column of its own and the scene is
   drawn beside it instead of underneath it. */
@media (min-width: 1100px) {
  body.briefing-open #scene-container {
    left: calc(var(--briefing-w) + 32px);
  }

  body.briefing-open .status-line {
    left: calc(var(--briefing-w) + 48px);
  }
}

/* On a phone the briefing comes up from the bottom, like the article. */
@media (max-width: 767px) {
  .briefing {
    top: auto;
    left: 8px;
    right: 8px;
    bottom: 8px;
    width: auto;
    max-width: none;
    height: 64vh;
    transform: translateY(14px);
  }
}

.briefing-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 12px 14px 2px;
}

.briefing-head h2 {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.briefing-count {
  font-size: 11px;
  color: var(--text-dim);
}

.briefing .close-btn {
  margin-left: auto;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.briefing .close-btn:hover {
  color: var(--text);
}

.briefing-note,
.briefing-empty {
  margin: 0;
  padding: 2px 14px 10px;
  font-size: 11px;
  color: var(--text-dim);
}

.briefing-empty {
  padding-top: 10px;
}

.no-scene-note {
  display: none;
}

.briefing-list {
  flex: 1 1 auto;
  margin: 0;
  padding: 0 6px 8px;
  overflow-y: auto;
  list-style: none;
  counter-reset: rank;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.16) transparent;
}

.briefing-list li {
  counter-increment: rank;
}

.brief-item {
  --tier-color: var(--tier-1);
  --tier-text: var(--tier-1-text);
  display: grid;
  grid-template-columns: 20px 1fr;
  column-gap: 8px;
  width: 100%;
  margin: 0 0 2px;
  padding: 9px 10px 9px 6px;
  background: transparent;
  border: 0;
  border-left: 3px solid var(--tier-color);
  border-radius: 2px;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.brief-item.tier-5 { --tier-color: var(--tier-5); --tier-text: var(--tier-5); }
.brief-item.tier-4 { --tier-color: var(--tier-4); --tier-text: var(--tier-4); }
.brief-item.tier-3 { --tier-color: var(--tier-3); --tier-text: var(--tier-3); }
.brief-item.tier-2 { --tier-color: var(--tier-2); --tier-text: var(--tier-2-text); }

.brief-item:hover,
.brief-item:focus-visible,
.brief-item.is-marked {
  background: rgba(255, 255, 255, 0.06);
}

/* The row whose planet is under the pointer. */
.brief-item.is-marked {
  box-shadow: inset 0 0 0 1px var(--accent);
}

.brief-item:focus-visible {
  outline-offset: -2px;
}

/* The place in the ranking. The list is an ordered list, so a screen reader
   already says the number. */
.brief-item::before {
  content: counter(rank);
  grid-row: 1 / span 3;
  padding-top: 2px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-dim);
}

.brief-item > span {
  grid-column: 2;
}

.brief-title {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
}

.brief-meta {
  margin-top: 4px;
  font-size: 11px;
  line-height: 1.35;
  color: var(--text-dim);
}

.brief-severity {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tier-text);
}

.brief-from {
  margin-top: 2px;
  font-size: 10.5px;
  color: var(--text-dim);
  opacity: 0.85;
}

/* --- no 3D: the list is the page ---------------------------------------- */

body.no-scene #scene-container,
body.no-scene .legend,
body.no-scene #briefing-toggle,
body.no-scene #briefing-close {
  display: none;
}

body.no-scene .no-scene-note {
  display: block;
}

body.no-scene .briefing {
  left: 16px;
  right: 16px;
  bottom: 52px;
  width: auto;
  max-width: 760px;
  height: auto;
  margin: 0 auto;
}

body.no-scene .status-line {
  left: 16px;
}

@media (max-width: 767px) {
  body.no-scene .briefing {
    top: 148px;
    left: 8px;
    right: 8px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .briefing {
    transition: none;
    transform: none;
  }
}

/* Where the list opens over the scene it also covers the status line, which
   would otherwise show through on top of the last row. */
@media (max-width: 1099px) {
  body.briefing-open:not(.no-scene) .status-line {
    visibility: hidden;
  }
}

/* --- what differs between the two readers -------------------------------- */

.mode-switch,
.filter-bar,
.refresh-btn,
.status-line,
.briefing,
.info-panel {
  border-radius: var(--radius);
}

body[data-mode="everyday"] .mode-switch button,
body[data-mode="everyday"] .filter-bar button {
  border-radius: 999px;
  text-transform: none;
  font-size: 13px;
  letter-spacing: 0;
}

body[data-mode="everyday"] .info-panel {
  background: rgba(22, 18, 62, 0.94);
}

body[data-mode="everyday"] .info-part p,
body[data-mode="everyday"] .info-part li {
  font-size: 14.5px;
}

body[data-mode="everyday"] .info-panel .actions a,
body[data-mode="everyday"] .info-panel .actions button {
  border-radius: 999px;
  text-transform: none;
  font-size: 13px;
}

body[data-mode="everyday"] .badge {
  border-radius: 999px;
  text-transform: none;
  font-size: 11.5px;
  letter-spacing: 0;
}

/* Planet labels. Everyday reads as a sentence; Professional as a readout. */
body[data-mode="everyday"] .planet-label {
  border-radius: 10px;
  background: rgba(20, 16, 58, 0.78);
}

body[data-mode="everyday"] .label-headline {
  font-size: 11px;
  letter-spacing: 0.01em;
  text-transform: none;
}

body[data-mode="professional"] .label-headline,
body[data-mode="professional"] .label-fact {
  font-family: var(--mono);
}

body[data-mode="professional"] .label-fact {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

/* The briefing's opening summary. */
.briefing-summary {
  padding: 0 10px 10px;
}

.summary-title {
  margin: 0 4px 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
}

.summary-action {
  display: block;
  width: 100%;
  margin-bottom: 5px;
  padding: 9px 12px;
  background: var(--accent);
  border: 0;
  border-radius: 10px;
  color: #17123f;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
}

.summary-action:hover {
  filter: brightness(1.08);
}

.summary-counts {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid var(--panel-border);
  background: var(--panel-border);
}

.summary-count {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 7px 4px;
  background: #080b12;
  text-align: center;
}

.summary-n {
  font: 600 16px/1 var(--mono);
  color: var(--text);
}

.summary-count.tier-5 .summary-n { color: var(--tier-5); }
.summary-count.tier-4 .summary-n { color: var(--tier-4); }

.summary-label {
  font: 8.5px/1.2 var(--mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* Rows. Everyday: a sentence and, where there is one, the thing to do. */
body[data-mode="everyday"] .brief-item {
  border-left-width: 4px;
  border-radius: 10px;
}

body[data-mode="everyday"] .brief-title {
  font-size: 14px;
}

body[data-mode="everyday"] .brief-meta {
  font-size: 12px;
}

body[data-mode="everyday"] .brief-severity {
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
}

.brief-action {
  margin-top: 5px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--accent);
}

.brief-action::before {
  content: "→ ";
}

.brief-divider {
  margin: 12px 6px 6px;
  padding-top: 10px;
  border-top: 1px solid var(--panel-border);
  counter-increment: none;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
}

/* Rows. Professional: the markers as tags. */
.brief-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 5px;
}

.brief-tag {
  padding: 2px 5px;
  border: 1px solid var(--panel-border);
  border-radius: 2px;
  font: 9.5px/1.3 var(--mono);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.brief-tag.brief-severity {
  border-color: currentColor;
  font-weight: 700;
  color: var(--tier-text);
}

.brief-tag.is-hot {
  border-color: var(--tier-5);
  color: var(--tier-5);
}

body[data-mode="professional"] .brief-title {
  font-size: 12.5px;
}

body[data-mode="professional"] .brief-from {
  font-family: var(--mono);
  font-size: 9.5px;
}

body[data-mode="professional"] .briefing-head h2 {
  font-family: var(--mono);
}

body[data-mode="everyday"] .briefing-head h2 {
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
}

body[data-mode="everyday"] .briefing-note {
  font-size: 12px;
}

/* --- first-run guide ------------------------------------------------------ */

.guide-backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(3, 5, 9, 0.72);
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms ease-out, visibility 0s linear 180ms;
}

.guide-backdrop.open {
  opacity: 1;
  visibility: visible;
  transition: opacity 180ms ease-out, visibility 0s;
}

.guide {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 41;
  /* Wide enough that the guide, with its choice about sensitive topics, fits
     a small laptop screen without scrolling. */
  width: 660px;
  max-width: calc(100vw - 32px);
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  padding: 22px 26px;
  background: #14113d;
  border: 1px solid rgba(196, 184, 255, 0.28);
  border-radius: 16px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
  color: #ece9ff;
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -50%) scale(0.97);
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s linear 160ms;
}

.guide.open {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, -50%) scale(1);
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s;
}

.guide:focus {
  outline: none;
}

.guide h2 {
  margin: 0 0 12px;
  font-size: 20px;
}

.guide h3 {
  margin: 16px 0 8px;
  font-size: 14px;
}

.guide-steps {
  margin: 0;
  padding-left: 22px;
  font-size: 14px;
  line-height: 1.5;
  color: #cfc9ee;
}

.guide-steps li + li {
  margin-top: 6px;
}

.guide-steps strong {
  color: #ffffff;
}

.guide-modes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 10px;
}

.guide-modes button {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(196, 184, 255, 0.35);
  border-radius: 12px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.guide-modes button:hover {
  background: rgba(196, 184, 255, 0.16);
}

.guide-modes strong {
  font-size: 15px;
}

.guide-modes span {
  font-size: 13px;
  line-height: 1.4;
  color: #cfc9ee;
}

.guide-done {
  margin-top: 10px;
  padding: 6px 0;
  background: none;
  border: 0;
  color: #c0b0ff;
  font: inherit;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  .guide,
  .guide-backdrop {
    transition: none;
  }

  .guide,
  .guide.open {
    transform: translate(-50%, -50%);
  }
}

/* --- what the refresh button says ---------------------------------------- */

.refresh-note {
  position: absolute;
  top: 62px;
  right: 16px;
  max-width: min(320px, calc(100vw - 32px));
  margin: 0;
  padding: 9px 13px;
  background: var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-size: 13px;
  line-height: 1.4;
  color: var(--text);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s linear 160ms;
}

.refresh-note.open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 160ms ease-out, transform 160ms ease-out, visibility 0s;
}

@media (max-width: 767px) {
  .refresh-note {
    top: auto;
    bottom: 52px;
    right: 8px;
    left: 8px;
    max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .refresh-note {
    transition: none;
    transform: none;
  }
}

/* --- the top bar as the window's title bar --------------------------------
   On anything wider than a phone there is one bar across the top of the
   window, and the scene starts beneath it. In the desktop app on Windows this
   bar is the title bar: the window is dragged by it, and Windows' own three
   buttons sit over its right-hand end, in the same colour (see chrome.js).

   The bar holds the name, the places to go and the reader switch, at every
   window size. The filters and the refresh button are not in it: they float
   over the top of the scene just beneath it. For a while a large window put
   them in the bar as well; the bar is kept to the few things that say where
   you are, and looks the same however big the window is. */

.brand-icon {
  display: block;
  flex: none;
  align-self: center;
}

@media (min-width: 768px) {
  .topbar {
    top: 0;
    left: 0;
    right: 0;
    height: var(--bar-h);
    gap: 14px;
    justify-content: flex-start;
    /* The right-hand end is left clear for the window's buttons. */
    padding: 0 calc(var(--controls-w, 0px) + 10px) 0 12px;
    background: var(--bar-bg);
    /* A line under the bar, drawn outside it so that it carries on beneath
       the window's buttons, which cover the bar's own height exactly. */
    box-shadow: 0 1px 0 var(--panel-border);
    pointer-events: auto;
    -webkit-app-region: drag;
    app-region: drag;
  }

  /* Everything that takes a click or a scroll is taken out of the part the
     window is dragged by. */
  .topbar a,
  .topbar button,
  .topbar .filter-bar {
    -webkit-app-region: no-drag;
    app-region: no-drag;
  }

  .topbar .brand,
  .topbar .mode-switch {
    background: none;
    border: 0;
    border-radius: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .topbar .brand {
    align-items: center;
    gap: 9px;
    padding: 0;
  }

  .topbar .mode-switch {
    padding: 0 14px;
    border-left: 1px solid var(--panel-border);
    border-right: 1px solid var(--panel-border);
    border-radius: 0;
  }

  /* Everything else starts below the bar. */
  #scene-container,
  .info-backdrop,
  .guide-backdrop {
    top: var(--bar-h);
  }

  .briefing {
    top: calc(var(--bar-h) + 12px);
  }

  /* The filters float over the top of the scene, beneath the bar. */
  .topbar .filter-bar {
    position: absolute;
    top: calc(var(--bar-h) + 12px);
    left: 16px;
    width: max-content;
    /* Room is left at the right for the refresh button. */
    max-width: calc(100% - 82px);
    margin: 0;
    /* One line, always. Where there is no room for all eleven, those at the
       end move into a "More" menu (see fitFilters in chrome.js), which has
       to be able to hang below the row. */
    flex-wrap: nowrap;
    gap: 4px;
    overflow: visible;
    border-radius: var(--radius);
  }

  .topbar .filter-bar button {
    flex: none;
    padding: 6px 10px;
    white-space: nowrap;
  }

  /* So does the refresh button, at the right-hand edge. */
  .topbar .refresh-btn {
    position: absolute;
    top: calc(var(--bar-h) + 15px);
    right: 16px;
    width: 34px;
    height: 34px;
    border-radius: var(--radius);
  }

  /* Its message drops below the button it sits under. */
  .refresh-note {
    top: calc(var(--bar-h) + 62px);
    z-index: 1;
  }

  /* Where the list is the whole page, it starts under the filters and not
     on top of them. */
  body.no-scene .briefing {
    top: calc(var(--bar-h) + 66px);
  }
}

/* Beside the list, the filters start where the scene does. */
@media (min-width: 1100px) {
  body.briefing-open:not(.no-scene) .topbar .filter-bar {
    left: calc(var(--briefing-w) + 48px);
    max-width: calc(100% - var(--briefing-w) - 114px);
  }
}

/* Where the list opens over the scene, it too starts under the filters. */
@media (min-width: 768px) and (max-width: 1099px) {
  .briefing {
    top: calc(var(--bar-h) + 66px);
  }
}

/* The browser preview has no refresh button, so the filters may use the
   room that is kept for it. */
@media (min-width: 768px) {
  html[data-source="static"] .topbar .filter-bar {
    max-width: calc(100% - 32px);
  }
}

@media (min-width: 1100px) {
  html[data-source="static"] body.briefing-open:not(.no-scene) .topbar .filter-bar {
    max-width: calc(100% - var(--briefing-w) - 64px);
  }
}

/* A phone has no room for the icon beside the name: with it, the refresh
   button is pushed onto a row of its own. */
@media (max-width: 767px) {
  .brand-icon {
    display: none;
  }
}

/* --- searching and sorting the briefing ---------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.briefing-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 10px 10px;
}

.briefing-search {
  position: relative;
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.05);
  color: var(--text-dim);
}

.briefing-search:focus-within {
  border-color: var(--accent);
  color: var(--text);
}

.briefing-search svg {
  flex: none;
}

.briefing-search input {
  flex: 1 1 auto;
  min-width: 0;
  height: 34px;
  padding: 0;
  background: none;
  border: 0;
  outline: none;
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.briefing-search input::placeholder {
  color: var(--text-dim);
}

.briefing-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 100%;
  font-size: 11px;
  color: var(--text-dim);
}

.briefing-sort select {
  flex: 1 1 auto;
  min-width: 0;
  height: 30px;
  padding: 0 28px 0 10px;
  appearance: none;
  -webkit-appearance: none;
  /* The list that drops down is drawn by the system; this asks for its dark
     form, to match. */
  color-scheme: dark;
  background: rgba(255, 255, 255, 0.05)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%23a9a3cf' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E")
    no-repeat right 10px center / 10px 7px;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  cursor: pointer;
}

.briefing-sort select:hover {
  border-color: var(--accent);
}

body[data-mode="professional"] .briefing-sort,
body[data-mode="professional"] .briefing-sort select,
body[data-mode="professional"] .briefing-search input {
  font-family: var(--mono);
}

body[data-mode="professional"] .briefing-sort {
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.briefing-summary[hidden] {
  display: none;
}

/* --- Stay safe ------------------------------------------------------------
   A page to read, not a scene to look round: the guides as cards, a group at
   a time, and the newest official warnings beneath them. It starts under the
   top bar (safe.js measures where that ends) and scrolls by itself, since the
   window never does. Like every screen it takes its colours and its corners
   from the reader it is set to. */

.safe-page {
  --card-bg: rgba(10, 14, 22, 0.84);
  --card-bg-hover: rgba(16, 22, 34, 0.94);
}

.safe-page[data-mode="everyday"] {
  --card-bg: rgba(27, 22, 72, 0.84);
  --card-bg-hover: rgba(38, 31, 96, 0.94);
}

.safe {
  position: fixed;
  inset: var(--safe-top, 48px) 0 0 0;
  z-index: 5;
  overflow-y: auto;
  padding: 30px 24px 60px;
  scrollbar-width: thin;
  scrollbar-color: var(--panel-border) transparent;
}

.safe > * {
  max-width: 1040px;
  margin-left: auto;
  margin-right: auto;
}

.safe-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 18px 28px;
  margin-bottom: 28px;
}

.safe-head h2 {
  margin: 0 0 6px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.safe-note {
  margin: 0;
  max-width: 58ch;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text-dim);
}

.safe-progress {
  display: grid;
  gap: 7px;
  min-width: 190px;
  font-size: 12px;
  color: var(--text-dim);
}

.safe-progress-track {
  display: block;
  height: 6px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--panel-border);
}

.safe-progress-track span {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 240ms ease-out;
}

.safe-group {
  margin-bottom: 34px;
}

.safe-group-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin-bottom: 12px;
}

.safe-group-head h3 {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

.safe-group-head p {
  margin: 0;
  font-size: 13px;
  color: var(--text-dim);
}

.safe-cards,
.tip-list {
  display: grid;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.safe-cards {
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
}

.safe-cards li,
.tip-list li {
  display: flex;
}

.safe-card {
  appearance: none;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr auto;
  align-items: center;
  gap: 10px 12px;
  width: 100%;
  padding: 16px;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: var(--card-bg);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color 140ms ease-out, background 140ms ease-out, transform 140ms ease-out;
}

.safe-card:hover,
.safe-card:focus-visible {
  background: var(--card-bg-hover);
  border-color: var(--accent);
  transform: translateY(-2px);
}

.safe-card-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--accent);
  border-radius: 2px;
  font: 600 12px/1 var(--mono);
  color: var(--accent);
}

.safe-card.is-done .safe-card-mark {
  background: var(--accent);
  color: var(--bg);
}

.safe-card-title {
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
}

.safe-card-short,
.safe-card-meta {
  grid-column: 1 / -1;
}

.safe-card-short {
  align-self: start;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-dim);
}

.safe-card-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 11.5px;
  color: var(--text-dim);
}

.safe-card.is-done .safe-card-meta > span:last-child {
  color: var(--accent);
}

/* Everyday: rounder and roomier, with the number in a circle. */
.safe-page[data-mode="everyday"] .safe-card {
  padding: 18px;
}

.safe-page[data-mode="everyday"] .safe-card-mark {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  font: 700 13px/1 inherit;
}

.safe-page[data-mode="everyday"] .safe-card-title {
  font-size: 15.5px;
}

.safe-page[data-mode="everyday"] .safe-card-short {
  font-size: 13.5px;
}

.tip-list {
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 12px 14px;
}

.tip {
  display: grid;
  align-content: start;
  gap: 6px;
  width: 100%;
  padding: 12px 14px;
  color: var(--text);
  text-decoration: none;
  background: var(--card-bg);
  border: 1px solid var(--panel-border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  transition: border-color 140ms ease-out, background 140ms ease-out;
}

.tip:hover,
.tip:focus-visible {
  background: var(--card-bg-hover);
  border-color: var(--accent);
}

.tip-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 9px;
  font-size: 11px;
  color: var(--text-dim);
}

.tip-source {
  font-weight: 600;
  color: var(--accent);
}

.tip-title {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
}

.tip-summary {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
}

.tips-empty,
.safe-foot {
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-dim);
}

.tips-empty {
  margin: 0;
}

.safe-foot {
  margin-top: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--panel-border);
}

/* One guide, open. Wider than an article, since it is there to be read
   through, and kept beneath the top bar however long it is. A phone keeps the
   bottom sheet every panel has there, a little taller. */
@media (min-width: 768px) {
  .info-panel.safe-reader {
    top: calc(50% + var(--bar-h) / 2);
    width: 600px;
    max-height: calc(100vh - var(--bar-h) - 32px);
    padding: 22px 24px;
  }

  /* Nothing follows the reader switch on this screen, so it needs no rule
     on its right. */
  .safe-page .topbar .mode-switch {
    border-right: 0;
  }
}

@media (max-width: 767px) {
  .info-panel.safe-reader {
    max-height: 78vh;
  }
}

.info-panel {
  scrollbar-width: thin;
  scrollbar-color: var(--panel-border) transparent;
}

.safe-reader h2 {
  font-size: 19px;
  line-height: 1.3;
}

.safe-why {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--text);
}

.info-part .safe-steps {
  margin: 0;
  padding-left: 22px;
}

.info-part .safe-steps li {
  padding-left: 4px;
}

.info-part .safe-steps li + li {
  margin-top: 9px;
}

.safe-steps li::marker {
  font-weight: 700;
  color: var(--accent);
}

.info-part .safe-sources {
  padding: 0;
  list-style: none;
}

.safe-sources a {
  color: var(--accent);
  text-underline-offset: 2px;
}

.brand .nav-link {
  white-space: nowrap;
}

.brand .nav-link.is-current {
  color: var(--accent);
}

/* On a phone the name and the places to go do not fit on one line. The name
   keeps the first and the places take the second, and the box is only as wide
   as the wider of the two, which leaves the refresh button its place beside
   it. */
@media (max-width: 767px) {
  .brand {
    display: grid;
    grid-template-columns: repeat(3, auto);
    justify-content: start;
    gap: 6px 10px;
  }

  .brand h1 {
    grid-column: 1 / -1;
  }

  .brand h1 + .nav-link {
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 767px) {
  .safe {
    padding: 18px 16px 48px;
  }

  .safe-head h2 {
    font-size: 22px;
  }

  .safe-progress {
    width: 100%;
  }

  .tip-list {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  .safe-card,
  .tip,
  .safe-progress-track span {
    transition: none;
  }

  .safe-card:hover,
  .safe-card:focus-visible {
    transform: none;
  }
}

/* From a line of advice in a story to the guide that says how to follow it. */
.how-link {
  font-weight: 600;
  white-space: nowrap;
  color: var(--accent);
  text-underline-offset: 2px;
}

/* --- sensitive topics ------------------------------------------------------
   The reader's choice about distressing subjects: what it is for, what it
   hides, and the two choices. Drawn in the first-run guide and, folded away,
   above the warnings on the Stay safe screen (see sensitive.mjs). */

.sensitive {
  font-size: 13.5px;
  line-height: 1.5;
}

.sensitive p {
  margin: 0;
}

.sensitive-what {
  margin-top: 6px !important;
  font-weight: 600;
}

.sensitive-list {
  margin: 3px 0 10px;
  padding-left: 20px;
}

.sensitive-choices {
  display: inline-flex;
  gap: 6px;
  padding: 4px;
  border: 1px solid var(--panel-border);
  border-radius: 999px;
}

.sensitive-choices button {
  padding: 6px 16px;
  background: none;
  border: 0;
  border-radius: 999px;
  color: inherit;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.sensitive-choices button:hover {
  background: rgba(255, 255, 255, 0.08);
}

.sensitive-choices button.active {
  background: var(--accent);
  color: var(--bg);
  font-weight: 600;
}

.sensitive-note {
  margin-top: 8px !important;
  font-size: 12.5px;
  opacity: 0.78;
}

/* In the guide, which keeps its own colours whichever reader is on. */
.guide .sensitive {
  color: #cfc9ee;
}

.guide .sensitive-choices {
  border-color: rgba(196, 184, 255, 0.35);
}

.guide .sensitive-choices button.active {
  background: #c0b0ff;
  color: #14113d;
}

/* On the Stay safe screen, under a line that says how it is set. */
.sensitive-fold {
  margin-bottom: 14px;
  background: var(--card-bg);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
}

.sensitive-fold summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--text-dim);
  list-style: none;
  cursor: pointer;
}

.sensitive-fold summary::-webkit-details-marker {
  display: none;
}

.sensitive-change {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.sensitive-fold[open] .sensitive-change {
  visibility: hidden;
}

.sensitive-fold .sensitive {
  padding: 2px 14px 14px;
  color: var(--text);
}

body:not([data-mode="everyday"]) .sensitive-choices,
body:not([data-mode="everyday"]) .sensitive-choices button {
  border-radius: 3px;
}

.guide .sensitive-choices,
.guide .sensitive-choices button {
  border-radius: 999px !important;
}

/* --- a newer version is ready ----------------------------------------------
   Desktop app only. Sits just above the status line and stays out of the way:
   it appears once the download is finished, and can be put off. */

.update-note {
  position: absolute;
  left: 16px;
  bottom: 54px;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100vw - 32px);
  padding: 8px 10px 8px 14px;
  background: var(--panel-bg);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-size: 13px;
  color: var(--text);
  pointer-events: auto;
}

.update-note[hidden] {
  display: none;
}

.update-note button {
  padding: 6px 12px;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  color: var(--bg);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.update-note button:disabled {
  opacity: 0.6;
  cursor: default;
}

.update-note .update-later {
  background: none;
  border-color: var(--panel-border);
  color: var(--text-dim);
  font-weight: 400;
}

body[data-mode="everyday"] .update-note button {
  border-radius: 999px;
}

/* It keeps to the status line: beside the briefing list when that is open
   next to the scene, and out of the way when the list is open over it. */
@media (min-width: 1100px) {
  body.briefing-open .update-note {
    left: calc(var(--briefing-w) + 48px);
  }
}

@media (max-width: 1099px) {
  body.briefing-open:not(.no-scene) .update-note {
    visibility: hidden;
  }
}

/* --- the browser preview ---------------------------------------------------
   The same pages are the desktop app and, on the web, a preview of it with no
   saving or pinning (see data.mjs). The hosted build marks the preview on the
   <html> tag. Anything "desktop-only" is not shown there, and anything
   "preview-only" is shown nowhere else. */

.preview-only {
  display: none !important;
}

html[data-source="static"] .preview-only {
  display: revert !important;
}

html[data-source="static"] .desktop-only {
  display: none !important;
}

/* Beside the name: says what this is, and leads to the download. */
.preview-tag {
  align-self: center;
  padding: 2px 8px;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.5;
  text-decoration: none;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--accent);
}

.preview-tag:hover {
  background: var(--accent);
  color: var(--bg);
}

body[data-mode="everyday"] .preview-tag {
  border-radius: 999px;
}

/* Where the Pin and Save buttons would be, and at the top of the guide. */
.preview-note {
  margin: 12px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
}

.preview-note a {
  font-weight: 600;
  white-space: nowrap;
  color: var(--accent);
  text-underline-offset: 2px;
}

.guide .preview-note {
  margin: 0 0 12px;
  padding: 8px 12px;
  border: 1px solid rgba(196, 184, 255, 0.35);
  border-radius: 10px;
  color: #cfc9ee;
}

.guide .preview-note a {
  color: #c0b0ff;
}

@media (max-width: 767px) {
  /* On a phone the label sits beside the name on the first line, and says
     only "Preview" so that the two fit the narrowest screens. The places to
     go take the second line. */
  html[data-source="static"] .brand h1 {
    grid-column: 1 / 3;
  }

  html[data-source="static"] .brand .preview-tag {
    grid-column: 3;
    grid-row: 1;
    justify-self: start;
  }

  .preview-tag .preview-tag-long {
    display: none;
  }

  /* Whichever link begins the second line has no rule on its left: the
     first after the label, or in the preview, where the Saved link is not
     shown, the one after that. */
  .brand h1 + .preview-tag + .nav-link,
  html[data-source="static"] .brand .preview-tag + .desktop-only + .nav-link {
    padding-left: 0;
    border-left: 0;
  }
}

/* --- the filters that do not fit -------------------------------------------
   On a window too narrow for all the filters, those at the end are moved into
   a menu behind a button at the end of the row (fitFilters in chrome.js). The
   button reads "More", or the name of the filter in the menu that is on. */

.filter-more {
  position: relative;
  display: flex;
  flex: none;
}

.filter-more[hidden] {
  display: none;
}

.filter-more-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

/* A small arrow, which turns over while the menu is open. */
.filter-more-toggle::after {
  content: "";
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
}

.filter-more.open .filter-more-toggle::after {
  transform: translateY(1px) rotate(-135deg);
}

.filter-more-menu {
  position: absolute;
  top: calc(100% + 13px);
  right: -7px;
  z-index: 2;
  display: none;
  flex-direction: column;
  gap: 4px;
  min-width: 180px;
  padding: 6px;
  background: rgba(10, 14, 22, 0.96);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.5);
}

body[data-mode="everyday"] .filter-more-menu {
  background: rgba(22, 18, 62, 0.97);
}

.filter-more.open .filter-more-menu {
  display: flex;
}

.topbar .filter-more-menu button {
  width: 100%;
  text-align: left;
}
