/* SEARCH-ENTRY-VISUAL-IMPLEMENTATION-1: the shared Multiplicity FM public
   entry layer.

   Authority: docs/projects/search-entry-surfaces-1/VISUAL-SYSTEM.md (Astra
   Pass 1, approved). Doctrine this file exists to hold: black is the main
   material, white carries meaning and colour carries orientation, a container
   must earn its edge, stillness is the premium state.

   SCOPE. Everything below is either an @font-face, a --pub-* custom property,
   or a rule under `.pub`. `.pub` is set on the <body> of exactly four public
   acquisition surfaces: /, /album-ranking, /listening-history, /apple-music.
   Nothing here can reach signed-in CAИON / ROTATIOИ / AИNUAL / LEDGER, the
   native shell, admin, dossiers or any other product surface, because none of
   them carries the class or links this file.

   It holds ONLY what is genuinely shared: typography, colour roles, spacing
   primitives, focus, action grammar, evidence typography, a small material
   vocabulary, reduced motion and responsive foundations. Page composition
   lives in each template, per repository convention. This is not a page
   builder, a section-card abstraction or a second token framework: the
   --mx-* system in foundation.css remains the product authority. */

/* ── Typeface ──────────────────────────────────────────────────────────────
   One variable file, self-hosted. `swap` so text paints immediately in the
   fallback and never goes invisible; the fallback stack is metrically close
   enough that the swap does not move a click target. Provenance and licence:
   static/fonts/manrope/PROVENANCE.md + OFL.txt. */
@font-face {
  font-family: "Manrope";
  src: url("/static/fonts/manrope/manrope-variable-latin-cyrillic.woff2") format("woff2-variations"),
       url("/static/fonts/manrope/manrope-variable-latin-cyrillic.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Faces */
  --pub-face: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Colour roles. VISUAL-SYSTEM.md §4. Contrast on #0E0F12: primary 17.57:1,
     secondary 10.12:1, metadata 7.26:1, cyan 12.45:1, magenta 6.89:1. */
  --pub-field: #070707;          /* dominant canvas */
  --pub-raised: #0e0f12;         /* contained proof, deliberate panels */
  --pub-hover: #14161a;          /* small interactive response only */
  --pub-ink: #f4f5f7;            /* headlines, values, meaningful labels */
  --pub-ink-2: #b7bdc4;          /* sustained reading */
  --pub-ink-3: #9aa0a6;          /* metadata, provenance */
  --pub-cyan: #90dced;           /* canonical F colour: action, focus, left light */
  --pub-cyan-soft: rgba(144, 220, 237, 0.22);
  --pub-cyan-wash: rgba(144, 220, 237, 0.06);
  --pub-pale: #f6f5f7;           /* canonical central stop */
  --pub-magenta: #ff668f;        /* canonical right-side energy, sparse */
  --pub-magenta-soft: rgba(255, 102, 143, 0.22);
  --pub-line: rgba(244, 245, 247, 0.12);       /* decorative border */
  --pub-line-strong: rgba(244, 245, 247, 0.2);
  --pub-edge: rgba(244, 245, 247, 0.3);        /* interactive edge */

  /* Spacing scale. Intermediate values resolve optical alignment only. */
  --pub-1: 4px;  --pub-2: 8px;  --pub-3: 12px; --pub-4: 16px; --pub-5: 24px;
  --pub-6: 32px; --pub-7: 48px; --pub-8: 64px; --pub-9: 96px; --pub-10: 128px;

  /* Section rhythm: major chapter gap, and the closer gap inside a chapter. */
  --pub-chapter: clamp(64px, 7vw, 120px);
  --pub-beat: clamp(32px, 4vw, 60px);

  /* Radii. Sleeves stay square; only containers round. */
  --pub-r-artefact: 20px;
  --pub-r-evidence: 12px;
  --pub-r-quiet: 8px;
  --pub-r-pill: 999px;

  /* Type. Desktop ≥1280 / mobile 390 anchors from VISUAL-SYSTEM.md §4,
     interpolated across the middle and capped rather than left to grow. */
  --pub-t-h1: clamp(34px, 5.2vw, 62px);
  --pub-t-h2: clamp(28px, 3.4vw, 42px);
  --pub-t-h2-read: clamp(26px, 2.6vw, 33px);
  --pub-t-h3: clamp(20px, 1.6vw, 23px);
  --pub-t-lede: clamp(17px, 1.35vw, 20px);
  --pub-t-body: clamp(16px, 1.1vw, 17px);
  /* ASTRA-PASS-3: these three reached their §4 desktop anchors only above
     ~1410px, so at 1280 - one of the two required desktop review widths -
     every small run on the three child surfaces rendered a step under its
     floor: supporting/receipt 14px against a 15-16px floor, metadata and
     provenance 12px against 13px, and evidence labels 11px against 12px.
     "In this listener's archive", "On plays alone" and "Once listening is
     read properly" are what make #157 -> #3 legible as a comparison of
     methods rather than a climb, and §4 is explicit that a meaningful label
     is "never tiny to force a single line". The coefficients now land each
     token on its desktop anchor at 1280 and hold its mobile anchor at 390;
     the anchors themselves are unchanged. */
  --pub-t-support: clamp(14px, 1.2vw, 16px);
  --pub-t-meta: clamp(12px, 1.05vw, 13px);
  --pub-t-eyebrow: clamp(11px, 0.95vw, 12px);
  --pub-t-rank: clamp(48px, 5.4vw, 76px);
  --pub-t-rank-compare: clamp(36px, 3.2vw, 46px);
}

/* ── Base ────────────────────────────────────────────────────────────────── */

.pub {
  font-family: var(--pub-face);
  background: var(--pub-field);
  color: var(--pub-ink);
  font-size: var(--pub-t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
}

.pub h1, .pub h2, .pub h3, .pub h4 { text-wrap: balance; }
.pub p, .pub li, .pub dd { text-wrap: pretty; }

/* Numbers that sit next to each other must line up. */
.pub [data-pub-num], .pub .pub-rank, .pub .pub-rank-b { font-variant-numeric: tabular-nums lining-nums; }

/* ── Type roles ──────────────────────────────────────────────────────────── */

.pub .pub-eyebrow {
  font-size: var(--pub-t-eyebrow);
  font-weight: 650;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pub-ink-3);
}

.pub .pub-h1 {
  font-size: var(--pub-t-h1);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.035em;
  color: var(--pub-ink);
}

.pub .pub-h2 {
  font-size: var(--pub-t-h2);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.03em;
  color: var(--pub-ink);
}

/* A reading chapter's heading: smaller, calmer, sits above prose. */
.pub .pub-h2--read {
  font-size: var(--pub-t-h2-read);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.pub .pub-h3 {
  font-size: var(--pub-t-h3);
  font-weight: 650;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--pub-ink);
}

.pub .pub-lede {
  font-size: var(--pub-t-lede);
  font-weight: 400;
  line-height: 1.55;
  color: var(--pub-ink-2);
  max-width: 52ch;
}

.pub .pub-body {
  font-size: var(--pub-t-body);
  line-height: 1.6;
  color: var(--pub-ink-2);
  max-width: 64ch;
}

.pub .pub-support {
  font-size: var(--pub-t-support);
  line-height: 1.5;
  color: var(--pub-ink-2);
  max-width: 64ch;
}

.pub .pub-meta {
  font-size: var(--pub-t-meta);
  font-weight: 500;
  line-height: 1.5;
  color: var(--pub-ink-3);
}

.pub strong, .pub b { font-weight: 650; color: var(--pub-ink); }

/* ── Evidence typography ─────────────────────────────────────────────────
   Shared grammar: label → value → receipt → provenance. The markup around it
   stays page-specific; only the voice of the type is common. */

.pub .pub-ev-label {
  display: block;
  font-size: var(--pub-t-eyebrow);
  font-weight: 650;
  letter-spacing: 0.08em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--pub-ink-3);
}

.pub .pub-ev-title {
  font-size: var(--pub-t-h3);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: var(--pub-ink);
}

.pub .pub-ev-sub {
  font-size: var(--pub-t-support);
  color: var(--pub-ink-2);
}

/* The interpreted rank: the page's largest number. */
.pub .pub-rank {
  display: block;
  font-size: var(--pub-t-rank);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--pub-ink);
}

/* The thing it is being compared against: quieter, never a competing peak. */
.pub .pub-rank-b {
  display: block;
  font-size: var(--pub-t-rank-compare);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--pub-ink-3);
}

.pub .pub-receipt {
  font-size: var(--pub-t-support);
  font-weight: 500;
  line-height: 1.5;
  color: var(--pub-ink);
}

.pub .pub-provenance {
  font-size: var(--pub-t-meta);
  font-weight: 500;
  line-height: 1.5;
  color: var(--pub-ink-3);
}

/* Album art. Square, barely rounded: never an app icon. */
.pub .pub-sleeve {
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 3px;
  background: #101114;
  overflow: hidden;
  flex: 0 0 auto;
}

.pub .pub-sleeve img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* If the artwork fails to load the box keeps its exact dimensions and the
     alt text reads as quiet metadata inside it, rather than as a broken-image
     glyph in body type. Nothing reflows. */
  font-size: 11px;
  line-height: 1.35;
  color: var(--pub-ink-3);
  overflow: hidden;
}

/* Missing-art fallback keeps the identical box, so nothing reflows. */
.pub .pub-sleeve-ph {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 1.6em;
  color: var(--pub-ink-3);
  background: linear-gradient(145deg, #131519, #0b0c0e);
}

/* ── Material ────────────────────────────────────────────────────────────
   Three tiers, and an explanation gets none of them. VISUAL-SYSTEM.md §4. */

/* Evidence object: contained proof. Quiet edge, neutral fill, no blur. */
.pub .pub-evidence {
  background: var(--pub-raised);
  border: 1px solid var(--pub-line);
  border-radius: var(--pub-r-evidence);
}

/* Flagship artefact: one per opening, one directional edge-light. */
.pub .pub-artefact {
  background: var(--pub-raised);
  border: 1px solid var(--pub-line);
  border-radius: var(--pub-r-artefact);
  box-shadow: 0 24px 60px -40px rgba(0, 0, 0, 0.9);
}

/* Supporting information: a rule, not a box. */
.pub .pub-ruled { border-top: 1px solid var(--pub-line); }

/* A short, precise edge of directional light. Decorative; never the only cue. */
.pub .pub-edge-cyan { box-shadow: inset 2px 0 0 var(--pub-cyan-soft); }
.pub .pub-edge-magenta { box-shadow: inset 2px 0 0 var(--pub-magenta-soft); }

/* ── Actions ─────────────────────────────────────────────────────────────
   One dominant action per existing decision group. Treatment follows the job;
   it never changes a destination or an order. */

.pub .mx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--pub-2);
  min-height: 48px;
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: var(--pub-r-pill);
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.pub .mx-btn--primary {
  background: var(--pub-cyan);
  color: #05171c;
  border-color: var(--pub-cyan);
}
.pub .mx-btn--primary:hover { background: #b2e8f5; border-color: #b2e8f5; }
.pub .mx-btn--primary:active { background: #7ccadc; }

.pub .mx-btn--secondary {
  background: transparent;
  color: var(--pub-ink);
  border-color: var(--pub-edge);
}
.pub .mx-btn--secondary:hover { background: var(--pub-hover); border-color: var(--pub-ink-2); }
.pub .mx-btn--secondary:active { background: #101216; }

/* Paired actions: existing DOM order, full width on a phone, 12px gap. */
.pub .pub-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pub-3);
  align-items: stretch;
}

/* Contextual link: inline, underlined, wraps with its own punctuation. A
   decorative arrow must never strand a full stop on its own line. */
.pub .pub-link {
  color: var(--pub-ink);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--pub-cyan-soft);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: text-decoration-color 140ms ease, color 140ms ease;
}
.pub .pub-link:hover {
  color: var(--pub-ink);
  text-decoration-color: var(--pub-cyan);
  text-decoration-thickness: 2px;
}

/* A proof/sample route inside a reading context: still a link, just louder. */
.pub .pub-link--action {
  display: inline;
  font-weight: 700;
  color: var(--pub-cyan);
  text-decoration-color: var(--pub-cyan-soft);
}
.pub .pub-link--action:hover { color: #b2e8f5; text-decoration-color: currentColor; }

/* ── Focus ──────────────────────────────────────────────────────────────
   Opaque cyan with dark separation, so it stays visible on a cyan control. */
.pub :focus-visible {
  outline: 2px solid var(--pub-cyan);
  outline-offset: 3px;
  border-radius: 4px;
  box-shadow: 0 0 0 5px var(--pub-field);
}

.pub .mx-skip-link,
.pub .pub-skip {
  position: absolute;
  left: var(--pub-4);
  top: var(--pub-4);
  z-index: 200;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 12px 18px;
  border-radius: var(--pub-r-quiet);
  background: var(--pub-cyan);
  color: #05171c;
  font-weight: 700;
  text-decoration: none;
  transform: translateY(calc(-100% - 24px));
  transition: transform 140ms ease;
}
.pub .mx-skip-link:focus,
.pub .pub-skip:focus { transform: translateY(0); }

/* ── Responsive foundations ─────────────────────────────────────────────── */

.pub .pub-shell {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--pub-5);
}

@media (min-width: 768px) { .pub .pub-shell { padding-inline: var(--pub-6); } }
@media (min-width: 1100px) { .pub .pub-shell { padding-inline: var(--pub-7); } }
@media (min-width: 1400px) { .pub .pub-shell { padding-inline: var(--pub-8); } }
@media (max-width: 359px) { .pub .pub-shell { padding-inline: var(--pub-4); } }

/* Actions go full width on a phone rather than shrinking their type. */
@media (max-width: 560px) {
  .pub .pub-actions { flex-direction: column; align-items: stretch; }
  .pub .pub-actions > .mx-btn { width: 100%; }
  .pub .mx-btn { padding: 12px 18px; height: auto; white-space: normal; }
}

/* ── Stillness ──────────────────────────────────────────────────────────
   Every surface must work fully with motion disabled: all content present
   immediately, no translation, no delay, focus still visible. */
@media (prefers-reduced-motion: reduce) {
  .pub *,
  .pub *::before,
  .pub *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .pub [class*="reveal"] { opacity: 1 !important; transform: none !important; }
}

/* ── ASTRA-PASS-3 finding B: the bug-report control stops covering the page ─
   Astra saw the fixed "Report a bug" control overlapping reading text on
   mobile. Reproduced on this branch at 390x844 on all three child surfaces:
   the pill sits fixed at z-index 9990, 101x26, `bottom: 76px`, over an opaque
   rgba(8,12,12,0.78) fill with a 14px backdrop blur - so the prose beneath it
   is not merely crowded, it is blurred out. At 320 it covered the "Get Mac
   access" control on /apple-music and a section jump link on
   /listening-history: an action, not just copy.

   VISUAL-SYSTEM.md §4 calls for this exact check ("fixed mobile Build and the
   live bug-report utility need explicit overlap checks"), requires that focus
   is not obscured by a fixed control, and bounds the remedy: "any remedy must
   use existing visibility/placement contracts and preserve destinations; no
   global widget redesign is part of this brief."

   So this is a placement change on four pages, not a widget change. The
   control already sits at the end of the document, after the footer, and its
   modal opens through the shared delegated `[data-mp-bug-open]` listener - the
   same contract app.py already relies on when it ships the affordance without
   the floating pill in the native shell and reaches it from a settings row
   instead. Below 640px it simply stops being an overlay and reads in flow,
   right-aligned under the footer. The element, its type, its data attribute,
   its label and the modal it opens are all untouched, and signed-in surfaces
   never see this rule because they do not carry `.pub`.

   It also picks up the two floors it was missing as a public action: a 44px
   target and an 11px label (§4 "at least 44 x 44px action targets"; the pill
   rendered a 9px label in a 26px box). */
@media (max-width: 640px) {
  .pub .mp-bug-link {
    position: static;
    inset: auto;
    z-index: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: max-content;
    min-height: 44px;
    margin: var(--pub-6) var(--pub-5) var(--pub-5) auto;
    padding: 0 var(--pub-4);
    font-size: 11px;
    opacity: 1;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
  }
}

@media (max-width: 359px) {
  .pub .mp-bug-link { margin-right: var(--pub-4); }
}

/* Above 640px the control keeps its fixed bottom-right placement, where the
   sweep found no collision at 1440 or 1280. It can still take keyboard focus
   under itself, so the document reserves its height for scrolling: WCAG 2.2
   Focus Not Obscured, which §4 names directly. */
@media (min-width: 641px) {
  html:has(.pub) { scroll-padding-bottom: 88px; }
}

/* bug-report.css sets `outline: none` on this control's `:focus-visible` and
   leaves colour and border-colour as the only focus signal. Tabbing to it on
   all three child surfaces showed no ring at 390, 320 or 1280. §4 requires
   visible keyboard focus and §8.12 that no action is conveyed through colour
   alone, so inside `.pub` it takes the same ring as every other public
   control. Scoped, so the signed-in widget is untouched. */
.pub .mp-bug-link:focus-visible {
  outline: 2px solid var(--pub-cyan);
  outline-offset: 3px;
  box-shadow: 0 0 0 5px var(--pub-field);
}
