@charset "utf-8";
/* ===========================================================================
   NEWSPORTVISION — foundations: fonts, reset, typography, a11y, materiality
   =========================================================================== */

/* --- Fonts, self-hosted ---------------------------------------------------
   Archivo carries wght 100–900 AND wdth 62–125. The width axis is load-
   bearing here: it is how a display line justifies to the measure without
   letterspacing tearing the word apart. */
@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("../fonts/archivo-normal-latin.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: "Archivo";
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url("../fonts/archivo-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-normal-latin.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: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-italic-latin.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: "Newsreader";
  font-style: italic;
  font-weight: 200 800;
  font-display: swap;
  src: url("../fonts/newsreader-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --- Fallback metrics ----------------------------------------------------
   Measured against the real faces (Archivo 600 and Newsreader 400): the
   adjusted fallbacks set to the same advance width and the same ascent, so
   when the web fonts arrive the text does not reflow. Where neither local
   face exists the rule simply does not apply and the plain stack is used. */
@font-face {
  font-family: "Archivo Fallback";
  src: local("Arial"), local("Helvetica Neue"), local("Helvetica"), local("Liberation Sans");
  size-adjust: 97.1%;
  ascent-override: 90.6%;
  descent-override: 21.6%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia"), local("Liberation Serif"), local("Times New Roman");
  size-adjust: 102.8%;
  ascent-override: 72%;
  descent-override: 25.3%;
  line-gap-override: 0%;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* the sticky header height, so #anchors do not land under it */
  scroll-padding-top: calc(var(--space-5) + var(--rule-bar));
  /* The scrollbar's lane is always reserved, so opening the menu (which stops
     the page scrolling) never shifts the composition sideways. */
  scrollbar-gutter: stable;
}
/* The menu is open: the page underneath holds still. */
html.menu-open { overflow: hidden; }
body {
  margin: 0;
  background: var(--nsv-paper);
  color: var(--nsv-ink);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  line-height: var(--lh-text);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg, video { display: block; max-width: 100%; }
[hidden] { display: none !important; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
/* Taps are answered at once and never read as a zoom gesture; the grey tap
   flash is replaced by each control's own pressed state. */
a, button, label, input, select, textarea, summary {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
/* A finger needs more to aim at than an eleven-pixel line of type. The small
   apparatus links carry an invisible hit area instead of padding, so the
   composition — and every rule drawn under a link — stays exactly where it is.
   The header's own nav is excluded: it is not shown at these sizes. */
@media (pointer: coarse) {
  a.meta, button.meta, .social a, .menu-foot a, .to-top, .hd-back,
  .editorial-end a, .legal-toc a { position: relative; }
  a.meta::before, button.meta::before, .social a::before, .menu-foot a::before,
  .to-top::before, .hd-back::before, .editorial-end a::before, .legal-toc a::before {
    content: "";
    position: absolute;
    inset: -11px -8px;
    z-index: 0;
  }
}
::selection { background: var(--selection-bg, var(--nsv-ink));
              color: var(--selection-fg, var(--nsv-yellow)); }

/* --- Focus ---------------------------------------------------------------
   Focus is the blue instrument colour, never brand yellow — so a focus ring
   can never be mistaken for a decorative field. */
:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--nsv-blue);
  outline-offset: 3px;
}
/* Blue reads at 6:1 on paper and on yellow, but only 2.4:1 on ink — so on the
   dark fields the ring is brand yellow instead (10.5:1). The ring is always
   one of the two, never the colour of the thing it is ringing. */
.on-ink :focus-visible, .skip-link:focus-visible { outline-color: var(--nsv-yellow); }
.on-yellow :focus-visible { outline-color: var(--nsv-blue); }

.skip-link {
  position: fixed;
  top: var(--space-2); left: var(--page-x);
  z-index: var(--z-skip);
  background: var(--nsv-ink);
  color: var(--nsv-yellow);
  font-family: var(--font-meta);
  font-size: var(--fs-meta);
  font-weight: 700;
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  padding: 14px 20px;
  transform: translateY(-200%);
  transition: transform var(--t-ui) var(--ease-enter);
}
.skip-link:focus-visible { transform: translateY(0); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* --- Typography roles ---------------------------------------------------- */

/* Display: signage. The institution's voice. */
.display, .h1, .h2, .h3 {
  font-family: var(--font-display);
  font-weight: var(--wght-display);
  font-variation-settings: "wdth" var(--wdth-normal);
  line-height: var(--lh-display);
  letter-spacing: var(--track-display);
  text-transform: uppercase;
  text-wrap: balance;
  hyphens: none;
  /* Italian legal headings carry words like "TRATTAMENTO" that are wider than
     a phone column on their own; break rather than run off the page. */
  overflow-wrap: break-word;
}
.h1 { font-size: var(--fs-h1); }
.h2 { font-size: var(--fs-h2); letter-spacing: var(--track-h); }
.h3 { font-size: var(--fs-h3); letter-spacing: var(--track-h); line-height: var(--lh-tight); }
.display  { font-size: var(--fs-display); }
.mega     { font-size: var(--fs-mega); font-weight: var(--wght-black); }

/* Reading: publication. The culture voice. */
.prose { font-family: var(--font-text); font-size: var(--fs-body); line-height: var(--lh-text); }
/* Bare URLs and long compounds live in this copy (bambasketballmovement…),
   and a narrow column must break them rather than push the page sideways. */
.prose, .lead, .legal-body, .cap p, .annot { overflow-wrap: anywhere; }
.prose p + p { margin-top: 1.1em; }
.lead {
  font-family: var(--font-text);
  font-size: var(--fs-lead);
  line-height: 1.38;
  /* Newsreader Light disappears on a saturated yellow ground; Regular holds. */
  font-weight: 400;
  text-wrap: pretty;
}
.measure    { max-width: 34em; }
.measure-sm { max-width: 26em; }

/* Meta: the apparatus. Labels, numbering, captions. */
.meta {
  font-family: var(--font-meta);
  font-size: var(--fs-meta);
  font-weight: 600;
  line-height: var(--lh-meta);
  letter-spacing: var(--track-meta);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.meta--quiet { color: var(--fg-quiet); }

/* Editorial annotation — the hand in the margin. */
.annot {
  font-family: var(--font-text);
  font-style: italic;
  font-size: var(--fs-small);
  font-weight: 300;
  line-height: 1.35;
  letter-spacing: 0;
  text-transform: none;
  color: var(--fg-quiet);
}

/* The NSV lockup, set at its own measured tracking. */
.lockup {
  font-family: var(--font-display);
  font-weight: var(--wght-black);
  letter-spacing: var(--track-lockup);
  line-height: var(--lh-display);
  text-transform: uppercase;
}

/* --- Materiality ----------------------------------------------------------
   A grain plate over the whole canvas. It exists so that large flat fields
   read as printed stock rather than as #FAC51C. At this strength it is
   invisible as an effect and only felt as a surface.

   The plates are black with the grain in their alpha channel, composited
   normally. Compositing black at alpha a is arithmetically the same as
   multiplying by (1 - a), so this darkens exactly as the multiply layer it
   replaces did — but a blend mode reads the page behind it, which means a
   fixed, full-screen blended layer has to be resolved against fresh content
   on every scrolled frame. This one is rasterised once and then simply
   composited, which is what made fast scrolling stutter on phones. */
.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: .042;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='g' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  -.3067 -.3067 -.3066 0 .64'/></filter><rect width='220' height='220' filter='url%28%23g%29'/></svg>");
  background-size: 220px 220px;
}
/* A second, much coarser plate: long fibres rather than even noise, so a
   large flat field reads as stock instead of as a fill. */
.grain::after {
  content: "";
  position: absolute; inset: 0;
  opacity: .5;
  background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='560' height='560'><filter id='g' color-interpolation-filters='sRGB'><feTurbulence type='fractalNoise' baseFrequency='0.008 0.62' numOctaves='2' seed='7' stitchTiles='stitch'/><feColorMatrix type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  -.3067 -.3067 -.3066 0 .64'/></filter><rect width='560' height='560' filter='url%28%23g%29'/></svg>");
  background-size: 560px 560px;
}
@media print { .grain { display: none; } }

/* --- Reduced motion -------------------------------------------------------
   Everything still arrives; it simply arrives without choreography. Nothing
   stays hidden, nothing depends on a scroll trigger to become readable. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
  /* Nothing may stay hidden because its animation was cancelled. This covers
     the reveal targets AND anything inside them that is held back by a
     transform — a rule waiting to be drawn, a bar waiting to be painted. */
  [data-reveal], [data-reveal] * ,
  .rule--draw, .axis__paint, .menu-list a, .hl > * {
    opacity: 1 !important;
    transform: none !important;
    translate: none !important;
    scale: none !important;
    clip-path: none !important;
    visibility: visible !important;
  }
  .grain { opacity: .03; }
}

/* --- Between pages --------------------------------------------------------
   Where the browser supports it, one page gives way to the next as a short
   cross-fade instead of a white flash. The header is the same object on
   every page, so it is carried across rather than faded. Nothing here runs
   under reduced motion, and a browser without support simply navigates. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
.site-header { view-transition-name: nsv-header; }
/* Leaving from the open menu, the menu is the page being left; the header
   hidden beneath it must not be lifted out on top of it. */
html.menu-open .site-header { view-transition-name: none; }
::view-transition-old(root) { animation: vt-out 160ms var(--ease-exit) both; }
::view-transition-new(root) { animation: vt-in 300ms var(--ease-enter) both; }
::view-transition-group(nsv-header) { animation-duration: 300ms; }
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in  { from { opacity: 0; } }

/* --- Print ---------------------------------------------------------------- */
@media print {
  body { background: #fff; color: #000; }
  .site-header, .menu-panel, .cursor, .to-top { display: none !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
