/* =============================================================================
   DMC ITALIA × KILLA COMBAT SCRATCH — stylesheet
   =============================================================================

   HOW TO EDIT
   -----------
   Everything tunable lives in the TOKENS block below. Change a token there and
   it propagates site-wide, mobile and desktop, in one edit.

     · Colours          → --black / --white / --red / --paper / --ink / --muted …
     · Type sizes       → --fs-*     (eight, one per role)
     · Page side margin → --edge     (16px <360 · 20px mobile · 64px tablet+ · centred @1200+)
     · Vertical rhythm  → --space-*  (five steps)

   THE TYPE SCALE — eight sizes for the whole site, no exceptions.
   Each one is a ROLE, not a number: pick by what the text IS, not by how big
   you want it to look. Mobile → desktop, fluid in between.

   Built mobile-first: the mobile column is the design target, the desktop
   column is what it's allowed to grow into.

     token          mobile → desktop   role
     --fs-gate       52 → 112   splash screen title only (brand, not content)
     --fs-hero       40 → 80    hero title            — H1
     --fs-title      32 → 50    page / section title  — H2
     --fs-sub        24 → 32    second-level heading  — H3
     --fs-body       16 → 17.5  body copy
     --fs-tagline    14 → 15    tagline, buttons, display-font links
     --fs-note       13         captions, meta, excerpts
     --fs-micro      12         badges, kickers, tags, form labels

   Two floors that are not negotiable on mobile:
     · body copy never below 16px
     · nothing carrying meaning below 12px (--fs-micro IS the floor)

   Never hardcode a font-size, a page-edge padding or a brand colour in a
   component — reach for a token. There is deliberately no room between these
   steps: if a size "feels wrong", the fix is picking the right role, not
   inventing a ninth value.

   Breakpoints: 820px (tablet/desktop) · 1200px (large desktop). Each component
   keeps its own responsive rules next to it, so a component is one place in
   this file, not three.

   SECTIONS
     1  Tokens            8  Buttons          15  Steps / stats / equip
     2  Reset & base      9  Hero             16  Generations + vinyl slider
     3  Gate             10  Marquee          17  Italian battles
     4  Site shell       11  Feature blocks   18  Crews
     5  Header           12  Contact form     19  Closing
     6  Language switch  13  Reveal           20  Category cards
     7  Mobile menu      14  Article          21  News list
                                              22  Honor roll
                                              23  Video lightbox
                                              24  News gallery
   ========================================================================== */

/* =============================================================================
   1 · TOKENS
   ========================================================================== */
:root{
  /* ---- brand colours ---- */
  --black:#0a0a0b;
  --white:#f4f3ee;
  --red:#ff2b1f;
  --grey:#8f8d86;

  /* RGB triplets, so any tint/alpha derives from the brand colour above
     instead of a copy-pasted rgba() literal */
  --black-rgb:10,10,11;
  --white-rgb:244,243,238;
  --red-rgb:255,43,31;

  /* ---- surface & text colours ---- */
  --paper:#eceae2;        /* light section background, info boxes           */
  --card:#fff;            /* cards, form inputs                             */
  --ink:#2c2c2a;          /* body copy on light backgrounds                 */
  --ink-soft:#3a3a38;     /* secondary body copy                            */
  --muted:#5c5b56;        /* captions, notes, meta                          */
  --cyan:#00e5ff;         /* glitch accent, display only                    */
  /* Brand red at 3.36:1 on ivory is below AA for small text. --red-ink is the
     same hue darkened to 5.27:1, used ONLY for small red text on light
     surfaces; --red itself is untouched for fills, large display type and
     anything on black, where it already passes. */
  --red-ink:#c8170d;

  --line:rgba(var(--white-rgb),.14);   /* hairline on dark */
  --line-dark:rgba(var(--black-rgb),.12); /* hairline on light */

  /* ---- fonts ---- */
  --display:'Big Shoulders Display', Impact, sans-serif;
  --display-weight:800;
  --body:'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  --serif:'EB Garamond', Garamond, serif;
  /* Etichette d'interfaccia (i tag delle news). Stesso carattere del pannello
     di redazione: un tag è un dato, non testo da leggere, e Inter alla stessa
     misura ha un occhio più grande che lo fa pesare più di quanto conti. */
  --ui:-apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* ---- THE TYPE SCALE — eight sizes, one per role ----
     Fluid between a 390px and a 1280px viewport, then fixed. To make all the
     body copy on the site bigger, change one number here; same for every
     heading level. Nothing else in this file sets a font-size. */
  --fs-gate:clamp(52px, 25.7px + 6.74vw, 112px);  /* splash title  — brand    */
  --fs-hero:clamp(40px, 22.5px + 4.49vw, 80px);   /* hero title    — H1       */
  --fs-title:clamp(32px, 24.1px + 2.02vw, 50px);  /* page title    — H2       */
  --fs-sub:clamp(24px, 20.5px + 0.90vw, 32px);    /* second level  — H3       */
  --fs-body:clamp(16px, 15.3px + 0.17vw, 17.5px); /* body copy — never below 16 */
  --fs-tagline:clamp(14px, 13.6px + 0.11vw, 15px);/* tagline, buttons, links  */
  --fs-note:13px;                                 /* captions, meta, excerpts */
  --fs-micro:12px;                                /* badges, kickers, labels
                                                     — the floor: nothing that
                                                     carries meaning goes below */

  /* ---- line heights ---- */
  --lh-flat:1;        /* numerals, single-line display */
  --lh-display:.95;   /* large headlines */
  --lh-title:1.1;     /* sub-headlines, card titles */
  --lh-snug:1.45;     /* dense UI lists, captions */
  --lh-text:1.6;      /* body copy — never tighter than 1.4 */

  /* ---- letter spacing ---- */
  --ls-display:.5px;  /* display-font links and titles */
  --ls-label:1.5px;   /* uppercase small labels */
  --ls-eyebrow:2px;   /* uppercase kickers */

  /* ---- vertical rhythm — five steps, matched to what they separate ---- */
  --space-2xs:10px;   /* label → title                       */
  --space-xs:14px;    /* paragraph → paragraph               */
  --space-sm:20px;    /* title → text                        */
  --space-md:28px;    /* related blocks                      */
  --space-lg:56px;    /* section → section                   */

  /* ---- layout ---- */
  --edge:20px;              /* page side margin — the single source of truth */
  --measure:46ch;           /* comfortable body column                      */
  --measure-long:64ch;      /* long-form reading column                     */
  --tap:44px;               /* minimum touch target                         */
  --radius:10px;
  --radius-lg:14px;

  /* ---- motion ---- */
  --ease:cubic-bezier(.16,1,.3,1);
  --ease-menu:cubic-bezier(.22,1,.36,1);
}

/* Very small phones: give the content back 8px of width. */
@media (max-width:359px){
  :root{ --edge:16px; }
}

/* Tablet and up: wider page margin. */
@media (min-width:820px){
  :root{
    --edge:64px;
    --measure:52ch;
  }
}

/* Large desktop: wider reading column, centred page margin. The type scale
   needs no breakpoint — every size is already fluid.
   NOTE --edge resolves 100% against the element's own containing block, so a
   component inside a multi-column grid (.feature) keeps the 64px floor while
   full-width components (.hdr, .article) centre against 1200px. That is the
   existing behaviour and is preserved deliberately. */
@media (min-width:1200px){
  :root{
    --edge:max(64px, calc((100% - 1200px) / 2));
    --measure-long:68ch;
  }
}

/* =============================================================================
   2 · RESET & BASE
   ========================================================================== */
*{ box-sizing:border-box; margin:0; padding:0; }

html{ -webkit-tap-highlight-color:transparent; }

/* Form controls don't inherit type from the page by default — without this a
   button with unstyled text falls back to the browser's own 13.33px system
   font, which is where the last stray sizes on the site came from. */
button, input, select, textarea{ font:inherit; }

body{
  background:var(--white);
  color:var(--black);
  font-family:var(--body);
  overflow-x:hidden;
}
body.locked{ overflow:hidden; height:100vh; }

a{ color:inherit; text-decoration:none; }
ul{ list-style:none; }
img{ max-width:100%; display:block; }

/* =============================================================================
   3 · GATE
   ========================================================================== */
.gate{
  position:fixed; inset:0; z-index:100;
  background:var(--black);
  color:var(--white);
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:24px;
  text-align:center;
  transition:transform .9s var(--ease);
}
.gate.is-open{ transform:translateY(-100%); }
.gate.is-hidden{ display:none; }

.gate__noise{
  position:absolute; inset:0;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.4'/%3E%3C/svg%3E");
  opacity:.06;
  pointer-events:none;
}

.gate__logos{
  display:flex; align-items:center; justify-content:center; gap:5%;
  width:100%;
  margin-bottom:var(--space-md);
  animation:gateFadeDown .85s var(--ease) both; animation-delay:.15s;
}
.gate__logo--dmc{ height:clamp(38px, 9vw, 64px); width:auto; }
.gate__logo--kcs{ height:clamp(85px, 20vw, 144px); width:auto; }

.gate__content{ position:relative; z-index:2; width:100%; padding:0 16px; }

.gate__kicker{
  font-size:var(--fs-micro); letter-spacing:var(--ls-label); font-weight:700;
  color:var(--red);
  margin-bottom:var(--space-sm);
  white-space:nowrap;
  animation:gateFadeDown .85s var(--ease) both; animation-delay:.48s;
}
.gate__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-gate);
  line-height:var(--lh-display);
  letter-spacing:var(--ls-display);
  width:100%;
}
.gate__title--dash{ color:var(--red); }
.gate__line{ display:block; }
.gate__line--1{ animation:gateSlideFromRight .75s var(--ease) both; animation-delay:.68s; }
.gate__line--2{ animation:gateSlideFromLeft .75s var(--ease) both; animation-delay:.92s; }
.gate__line--3{
  position:relative;
  color:var(--red);
  animation:gateLineFade .35s var(--ease) both;
  animation-delay:1.15s;
}
.gate__line--3::before,
.gate__line--3::after{
  content:attr(data-text);
  position:absolute; inset:0;
  color:var(--red);
  background:var(--black);
  opacity:0;
}
.gate__line--3::before{
  clip-path:inset(0 0 55% 0);
  animation:gateSplitTop 1.05s steps(1,end) both;
  animation-delay:1.15s;
}
.gate__line--3::after{
  clip-path:inset(45% 0 0 0);
  animation:gateSplitBottom 1.05s steps(1,end) both;
  animation-delay:1.15s;
}

.gate__enter{
  position:absolute; bottom:28px; left:50%; transform:translateX(-50%); z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:14px;
  color:var(--grey);
  cursor:pointer;
  background:none; border:none;
  padding:8px 16px;
}
.gate__enter p{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); text-transform:uppercase;
  transition:color .25s var(--ease);
}
.gate__enter:hover p{ color:var(--white); }
.gate__enter-ring{
  position:relative;
  width:12px; height:12px;
  border-radius:50%;
  background:var(--red);
}
.gate__enter-ring::before,
.gate__enter-ring::after{
  content:'';
  position:absolute; inset:0;
  border-radius:50%;
  border:1px solid var(--red);
  animation:gateEnterPulse 1.8s var(--ease) infinite;
}
.gate__enter-ring::after{ animation-delay:.6s; }

@media (min-width:1200px){
  .gate__content{ max-width:900px; padding:0 40px; }
}

@keyframes gateFadeDown{
  from{ opacity:0; transform:translateY(-24px); }
  to{ opacity:1; transform:translateY(0); }
}
@keyframes gateSlideFromRight{
  from{ opacity:0; transform:translateX(70px); }
  to{ opacity:1; transform:translateX(0); }
}
@keyframes gateSlideFromLeft{
  from{ opacity:0; transform:translateX(-70px); }
  to{ opacity:1; transform:translateX(0); }
}
@keyframes gateLineFade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes gateSplitTop{
  0%{ opacity:0; transform:translateX(0); }
  14%{ opacity:1; transform:translateX(-22px); }
  28%{ transform:translateX(16px); }
  42%{ transform:translateX(-11px); }
  56%{ transform:translateX(7px); }
  70%{ transform:translateX(-4px); }
  84%{ transform:translateX(2px); }
  100%{ opacity:0; transform:translateX(0); }
}
@keyframes gateSplitBottom{
  0%{ opacity:0; transform:translateX(0); }
  14%{ opacity:1; transform:translateX(22px); }
  28%{ transform:translateX(-16px); }
  42%{ transform:translateX(11px); }
  56%{ transform:translateX(-7px); }
  70%{ transform:translateX(4px); }
  84%{ transform:translateX(-2px); }
  100%{ opacity:0; transform:translateX(0); }
}
@keyframes gateEnterPulse{
  0%{ transform:scale(1); opacity:.9; }
  100%{ transform:scale(3); opacity:0; }
}

/* =============================================================================
   4 · SITE SHELL
   ========================================================================== */
.site{ display:none; }
.site.is-visible{ display:block; }

/* =============================================================================
   5 · HEADER
   ========================================================================== */
.hdr{
  position:fixed; top:0; left:0; right:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between;
  padding:20px var(--edge);
  background:none; border:none;
  transition:padding .35s var(--ease);
}
.hdr::before{
  content:"";
  position:absolute; inset:0; z-index:-1;
  background:linear-gradient(180deg,
    rgba(var(--black-rgb),.6) 0%,
    rgba(var(--black-rgb),.22) 65%,
    transparent 100%);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  -webkit-mask-image:linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  mask-image:linear-gradient(180deg, #000 0%, #000 55%, transparent 100%);
  opacity:0;
  pointer-events:none;
  transition:opacity .35s var(--ease);
}
.hdr.is-scrolled::before{ opacity:1; }
.hdr.is-scrolled{ padding-top:12px; padding-bottom:12px; }

.hdr__logo{
  display:flex; align-items:center; gap:8px;
  font-family:var(--display); font-weight:var(--display-weight);
}
.hdr__logo-img{
  display:block; width:auto;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.5));
  transition:height .35s var(--ease);
}
.hdr__logo-img--dmc{ height:33px; }
.hdr__logo-img--kcs{ height:74px; }
.hdr.is-scrolled .hdr__logo-img--dmc{ height:22px; }
.hdr.is-scrolled .hdr__logo-img--kcs{ height:46px; }

.hdr__actions{ display:flex; align-items:center; gap:16px; }

.hdr__burger{
  position:relative;
  width:68px; height:68px;
  background:none; border:none; border-radius:50%;
  cursor:pointer; overflow:visible;
  padding:0;
  filter:drop-shadow(0 2px 8px rgba(0,0,0,.35));
  transition:width .35s var(--ease), height .35s var(--ease);
}
.hdr.is-scrolled .hdr__burger{ width:50px; height:50px; }

.burger-vinyl{
  position:absolute; inset:0; width:100%; height:100%;
  animation:burgerSpin 14s linear infinite;
}
.burger-vinyl__disc{ fill:var(--black); }
.burger-vinyl__groove{ fill:none; stroke:rgba(var(--white-rgb),.4); stroke-width:1.2; }
.burger-vinyl__label{ fill:var(--red); }
@keyframes burgerSpin{ to{ transform:rotate(360deg); } }

.burger-lines{
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:15px; display:flex; flex-direction:column; gap:4px;
  pointer-events:none;
  transition:width .35s var(--ease), gap .35s var(--ease);
}
.hdr.is-scrolled .burger-lines{ width:12px; gap:3px; }
.burger-lines span{
  width:100%; height:1px; background:var(--white);
  transition:transform .3s var(--ease), opacity .3s;
}
.hdr__burger[aria-expanded="true"] .burger-lines span:nth-child(1){ transform:translateY(5px) rotate(45deg); }
.hdr__burger[aria-expanded="true"] .burger-lines span:nth-child(2){ opacity:0; }
.hdr__burger[aria-expanded="true"] .burger-lines span:nth-child(3){ transform:translateY(-5px) rotate(-45deg); }

/* On a phone the header holds one size and stops moving: the shrink-on-scroll
   and the spinning vinyl were animating over the page on every scroll frame.
   The compact size is the one the header keeps while reading, so that is the
   one that stays — with the KCS badge lifted enough for its ring text to
   survive, since at 38px it turned to mush. The burger still morphs into the
   close X: that is a response to a tap, not scroll motion. */
@media (max-width:819px){
  .hdr,
  .hdr::before,
  .hdr__logo-img,
  .hdr__burger,
  .burger-lines{ transition:none; }
  .burger-vinyl{ animation:none; }
  /* always on, so the backdrop does not snap in at the first scroll */
  .hdr::before{ opacity:1; }

  .hdr,
  .hdr.is-scrolled{ padding-top:12px; padding-bottom:12px; }
  .hdr__logo-img--dmc,
  .hdr.is-scrolled .hdr__logo-img--dmc{ height:22px; }
  .hdr__logo-img--kcs,
  .hdr.is-scrolled .hdr__logo-img--kcs{ height:46px; }
  .hdr__burger,
  .hdr.is-scrolled .hdr__burger{ width:50px; height:50px; }
  .burger-lines,
  .hdr.is-scrolled .burger-lines{ width:12px; gap:3px; }
}

/* =============================================================================
   6 · LANGUAGE SWITCH
   ========================================================================== */
.lang-switch{ display:flex; align-items:center; gap:6px; }
.lang-switch__link{
  /* The glyph is only ~15×17px but needs a 44px touch target. Sizing the box
     itself would steal ~50px of header width and crowd the KCS logo on narrow
     phones, so the target is an invisible overlay instead: it is out of flow,
     so it costs no layout space. */
  position:relative;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-label);
  color:var(--white);
  transition:color .2s var(--ease);
}
.lang-switch__link::after{
  content:'';
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:max(100%, var(--tap)); height:var(--tap);
}
a.lang-switch__link:hover{ color:var(--red); }
.lang-switch__link.is-active{ color:var(--red); }
.lang-switch__sep{ color:var(--line); font-size:var(--fs-note); }

/* =============================================================================
   7 · MOBILE MENU
   ========================================================================== */
.menu{
  position:fixed; inset:0; z-index:40;
  background:var(--black); color:var(--white);
  display:flex; flex-direction:column; justify-content:space-between;
  padding:100px 24px 40px;
  clip-path:circle(0% at var(--burger-x, calc(100% - 82px)) var(--burger-y, 82px));
  transition:clip-path .6s var(--ease-menu), visibility 0s linear .6s;
  visibility:hidden;
  pointer-events:none;
}
.menu.is-open{
  clip-path:circle(150% at var(--burger-x, calc(100% - 82px)) var(--burger-y, 82px));
  visibility:visible;
  transition:clip-path .6s var(--ease-menu);
  pointer-events:auto;
}
.menu__list li{ border-bottom:1px solid var(--line); }
.menu__list a{
  display:block; padding:18px 2px;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub);
  text-transform:uppercase;
}
.menu__row{ display:flex; align-items:center; justify-content:flex-start; gap:2px; }
.menu__row a{ flex:none; }

.menu__subtoggle{
  flex:none; background:none; border:none; padding:12px; margin:-12px 0;
  cursor:pointer; color:var(--white);
}
.menu__chevron{
  width:18px; height:18px;
  fill:none; stroke:currentColor; stroke-width:2.4; stroke-linecap:round; stroke-linejoin:round;
  transition:transform .3s var(--ease);
}
.menu__subtoggle[aria-expanded="true"] .menu__chevron{ transform:rotate(180deg); }

.menu__sublist{ display:none; padding:0 0 14px; }
.menu__sublist.is-open{ display:block; }
.menu__sublist li{ border-bottom:none; }
.menu__sublist a{
  display:block; padding:9px 2px;
  font-family:var(--body); font-weight:600;
  font-size:var(--fs-tagline); text-transform:none;
  color:var(--grey);
}
.menu__sublist a:hover{ color:var(--white); }

.menu__foot{ display:flex; flex-direction:column; gap:16px; }
.menu__sponsor{ display:flex; align-items:center; gap:10px; padding:18px 2px; }
.menu__sponsor-label{
  font-size:var(--fs-micro); letter-spacing:var(--ls-label); text-transform:uppercase;
  color:var(--grey); font-weight:700;
}
.menu__sponsor-logo{ height:20px; width:auto; }

.menu__social{ display:flex; gap:14px; }
.menu__social a{
  display:flex; align-items:center; justify-content:center;
  width:48px; height:48px;
  border:1px solid var(--line); border-radius:50%;
  color:var(--white);
  transition:border-color .25s var(--ease), color .25s var(--ease);
}
.menu__social a:hover{ border-color:var(--red); color:var(--red); }
.menu__social svg{ width:22px; height:22px; fill:currentColor; }

.menu__credit{ color:var(--grey); font-size:var(--fs-note); line-height:var(--lh-text); }
.menu__credit a{ color:var(--white); white-space:nowrap; }
.menu__credit a:hover{ color:var(--red); }
.menu__credit-neotokyo{
  font-family:var(--serif);
  font-style:italic;
  font-size:var(--fs-body);
  color:var(--white);
}

@media (min-width:820px){
  .menu__list a,
  .menu__sublist,
  .menu__credit{ text-align:center; }
  .menu__row,
  .menu__sponsor,
  .menu__social{ justify-content:center; }
}

/* =============================================================================
   8 · BUTTONS
   ========================================================================== */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-label);
  padding:15px 24px;
  border-radius:100px;
  border:2px solid var(--black);
  /* The links that carry .btn inherit page colours; a <button> would take the
     browser's grey chrome instead, so the base state is spelled out here. Both
     modifiers below set their own and win, being later in the file. */
  background:transparent; color:var(--black);
  transition:transform .2s var(--ease), background .2s, color .2s;
}
.btn:active{ transform:scale(.96); }
.btn--solid{ background:var(--black); color:var(--white); }
.btn--outline-light{ background:transparent; border-color:var(--white); color:var(--white); }

/* =============================================================================
   9 · HERO
   ========================================================================== */
.hero{
  position:relative;
  min-height:100svh;
  display:flex; align-items:flex-end;
  overflow:hidden;
}
.hero--sub{ min-height:64vh; }

.hero__bg{ position:absolute; inset:0; z-index:0; }
/* <picture> is inline by default, so the img inside it would have no height to
   fill — the random photo heroes wrap their img to offer a WebP source */
.hero__bg picture{ display:block; width:100%; height:100%; }
.hero__bg img,
.hero__bg video{ width:100%; height:100%; object-fit:cover; display:block; }
/* The pool photos from partials/hero-random.php are all framed the same way:
   the decks and the DJ's hands sit in the bottom third. A centred cover crop
   in a hero this wide eats exactly that band, so anchor the frame to its
   bottom edge and let the crop take the ceiling instead. Only the <picture>
   heroes come from the pool — storia's mixer and the contatti shot are
   centre-framed and stay that way. */
.hero__bg picture img{ object-position:50% 100%; }

.hero__scrim{
  position:absolute; inset:0;
  background:linear-gradient(180deg,
    rgba(var(--black-rgb),.05) 0%,
    rgba(var(--black-rgb),.35) 55%,
    rgba(var(--black-rgb),.92) 100%);
}
.hero__scrim--red{
  background:linear-gradient(180deg,
    rgba(var(--black-rgb),.1) 0%,
    rgba(var(--red-rgb),.28) 55%,
    rgba(var(--black-rgb),.94) 100%);
}
/* Pages that draw their hero photo from partials/hero-random.php can get any
   frame of the pool, with lit subjects anywhere — including right behind the
   kicker, which sits high up where the vertical scrim above is still nearly
   clear. So wash the left column, where the hero text actually lives, instead
   of darkening the whole frame. Composes on top of either scrim variant. */
.hero__scrim--photo::after{
  content:''; position:absolute; inset:0;
  background:linear-gradient(100deg,
    rgba(var(--black-rgb),.78) 0%,
    rgba(var(--black-rgb),.62) 30%,
    rgba(var(--black-rgb),.28) 55%,
    rgba(var(--black-rgb),0) 78%);
}

.hero__text{ position:relative; z-index:1; padding:40px var(--edge) 56px; width:100%; }

.hero__kicker{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  color:var(--red); margin-bottom:var(--space-xs);
}
.hero__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-hero);
  line-height:var(--lh-display);
  margin-bottom:var(--space-sm);
  color:var(--white);
}
.hero__title span{ color:var(--red); }
.hero__body{
  color:rgba(var(--white-rgb),.85);
  font-size:var(--fs-body); line-height:var(--lh-text);
  max-width:var(--measure); margin-bottom:var(--space-md);
}

/* mobile hero shows just the title — kicker + body come back from tablet up */
.hero__kicker,
.hero__body{ display:none; }
@media (min-width:820px){
  .hero__kicker,
  .hero__body{ display:block; }
  .hero--sub{ min-height:calc(52vh + 250px); }
}

.hero__caption{
  padding:18px var(--edge);
  background:var(--paper); color:var(--muted);
  font-size:var(--fs-note); line-height:var(--lh-snug);
  border-bottom:1px solid var(--line-dark);
}

/* home: hero + marquee share the first viewport together. The title block
   stays bottom-anchored like every other hero on the site — no special case. */
.hero-group{ min-height:100svh; display:flex; flex-direction:column; }
.hero-group .hero{ min-height:0; flex:1 1 auto; }

/* scroll cue */
.hero-scroll{
  display:flex; flex-direction:column; align-items:flex-start; gap:10px;
  color:var(--grey);
  margin-top:var(--space-sm);
}
.hero-scroll p{ font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); text-transform:uppercase; }
.hero-scroll__track{
  position:relative; width:2px; height:34px;
  background:var(--line); border-radius:2px; overflow:hidden;
}
.hero-scroll__cursor{
  position:absolute; left:50%; width:18px; height:8px;
  transform:translateX(-50%);
  background:var(--red); border-radius:1px;
  animation:swipeCursor 1.6s cubic-bezier(.45,0,.55,1) infinite;
}
@keyframes swipeCursor{
  0%{ top:-14px; opacity:0; }
  15%{ opacity:1; }
  85%{ opacity:1; }
  100%{ top:34px; opacity:0; }
}

/* Normal-flow (not absolutely positioned) on purpose: as the last item inside
   .hero__text it automatically shares the exact same left inset as the title /
   kicker / body at every breakpoint, with no padding value to keep in sync. */
.hero__video-tag{
  display:inline-flex; align-items:center; gap:8px;
  color:var(--white); font-size:var(--fs-micro); letter-spacing:var(--ls-display);
  background:rgba(var(--black-rgb),.45);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  padding:7px 14px; border-radius:100px;
  margin-top:var(--space-sm);
  flex:none;
}
.hero__video-tag-dot{
  width:7px; height:7px; border-radius:50%; background:var(--red); flex:none;
  animation:heroVideoTagBlink 1.4s ease-in-out infinite;
}
@keyframes heroVideoTagBlink{ 0%,100%{ opacity:1; } 50%{ opacity:.25; } }

/* home hero: on mobile the scroll cue is dropped and the video tag takes its
   spot (plain text, no badge); from tablet up the scroll cue stays and the tag
   becomes a badge pinned near the kicker, right-aligned on the page margin */
@media (max-width:819px){
  .hero-group .hero-scroll{ display:none; }
  .hero-group .hero__video-tag{
    background:none; backdrop-filter:none; -webkit-backdrop-filter:none;
    padding:0; margin-top:var(--space-sm);
  }
}
@media (min-width:820px){
  .hero-group .hero__video-tag{
    position:absolute; top:40px; right:var(--edge); z-index:2; margin-top:0;
  }
}

/* hero entrance */
.hero__kicker,
.hero__title,
.hero__body{ animation:heroReveal .7s var(--ease) both; }
.hero__kicker{ animation-delay:.05s; }
.hero__title{ animation-delay:.15s; }
.hero__body{ animation-delay:.35s; }
@keyframes heroReveal{
  from{ opacity:0; transform:translateY(18px); }
  to{ opacity:1; transform:translateY(0); }
}

/* the entrance is a homepage flourish — subpages open static */
.hero--sub .hero__kicker,
.hero--sub .hero__title,
.hero--sub .hero__body{ animation:none; }

.hero__title--glitch{ animation:glitchIn .9s steps(1,end) both; animation-delay:.15s; }
@keyframes glitchIn{
  0%{ opacity:0; transform:translate(0,0); text-shadow:none; }
  8%{ opacity:1; transform:translate(-6px,2px); text-shadow:3px 0 var(--red), -3px 0 var(--cyan); }
  18%{ transform:translate(5px,-2px); text-shadow:-3px 0 var(--red), 3px 0 var(--cyan); }
  28%{ transform:translate(-4px,1px); text-shadow:2px 0 var(--red), -2px 0 var(--cyan); }
  40%{ transform:translate(3px,-1px); text-shadow:-2px 0 var(--red), 2px 0 var(--cyan); }
  55%{ transform:translate(-2px,0); text-shadow:1px 0 var(--red), -1px 0 var(--cyan); }
  70%{ transform:translate(2px,0); text-shadow:-1px 0 var(--red), 1px 0 var(--cyan); }
  85%{ transform:translate(-1px,0); text-shadow:none; }
  100%{ opacity:1; transform:translate(0,0); text-shadow:none; }
}

/* =============================================================================
   10 · MARQUEE
   ========================================================================== */
.marquee{
  background:var(--black); color:var(--white);
  overflow:hidden; white-space:nowrap;
  padding:22px 0;
  border-top:1px solid var(--line); border-bottom:1px solid var(--line);
}
.marquee__track{
  display:inline-flex; gap:32px; align-items:center;
  animation:scroll 26s linear infinite;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub); letter-spacing:var(--ls-label); text-transform:uppercase;
}
.marquee__dot{ color:var(--red); font-size:var(--fs-note); }
@keyframes scroll{ from{ transform:translateX(0); } to{ transform:translateX(-50%); } }

/* =============================================================================
   11 · FEATURE BLOCKS
   ========================================================================== */
.features{ display:flex; flex-direction:column; }

.feature{ position:relative; padding:var(--space-lg) var(--edge); overflow:hidden; }
.feature--dark{ background:var(--black); color:var(--white); }
.feature--red{ background:var(--red); color:var(--white); }
.feature--light{ background:var(--paper); color:var(--black); }

.feature__art{
  position:absolute; right:0; bottom:0;
  width:72%; max-width:420px; height:auto;
  opacity:.9; pointer-events:none; z-index:0;
}
.feature--red .feature__art{ width:90%; max-width:560px; }

.feature__tag,
.feature__title,
.feature__stat,
.feature__body,
.feature__links,
.feature__social{ position:relative; z-index:1; }

.feature__tag{
  display:block; font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  opacity:.75; margin-bottom:var(--space-xs);
}
.feature--light .feature__tag{ color:var(--red-ink); opacity:1; }

.feature__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-hero);
  line-height:var(--lh-display); margin-bottom:var(--space-sm);
}
.feature__stat{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; color:var(--red);
  font-size:var(--fs-sub); line-height:var(--lh-title); margin-bottom:var(--space-xs);
}
.feature--red .feature__stat{ color:var(--black); }

.feature__body{
  max-width:var(--measure); line-height:var(--lh-text); opacity:.9;
  margin-bottom:var(--space-sm); font-size:var(--fs-body);
}
.feature--light .feature__body{ color:var(--ink-soft); opacity:1; }

.feature__links{
  display:flex; flex-direction:column; gap:10px;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display);
}
.feature__links a{
  /* inline link padded out to the 44px touch minimum without changing the
     visual rhythm: the extra height is absorbed by the negative margin */
  width:fit-content; display:inline-flex; align-items:center;
  min-height:var(--tap); margin-block:calc((var(--tap) - 1.4em) / -2);
}
.feature__links a::after{ content:'→'; display:inline-block; margin-left:6px; transition:transform .25s var(--ease); }
.feature__links a:hover::after{ transform:translateX(5px); }
.feature--light .feature__links a{ color:var(--red-ink); }

.feature__social{ display:flex; gap:16px; }
.feature__social a{
  display:flex; align-items:center; justify-content:center;
  width:58px; height:58px;
  border:1px solid var(--line); border-radius:50%;
  color:var(--white);
  transition:border-color .25s var(--ease), color .25s var(--ease);
}
.feature__social a:hover{ border-color:var(--red); color:var(--red); }
.feature__social svg{ width:28px; height:28px; fill:currentColor; }

.feature--social{ text-align:center; }
.feature--social .feature__body{ margin-left:auto; margin-right:auto; }
.feature--social .feature__social{ justify-content:center; }

.feature-media{ display:block; min-height:260px; overflow:hidden; }
.feature-media img{ width:100%; height:100%; min-height:260px; object-fit:cover; display:block; }

/* la locandina non è una foto: ritagliarla le mangerebbe titolo o data, quindi
   sta dentro il riquadro intera. Il fondo è il bianco della locandina stessa
   (#f8f8f8), così le bande che avanzano non si vedono: se un giorno cambia
   l'immagine, questo è il colore da riallineare. */
.feature-media--right{ background:#f8f8f8; }
.feature-media--right img{ object-fit:contain; }

@media (min-width:820px){
  /* Tre righe da due celle, più la fascia social a tutta larghezza. Le righe
     in fr, su una griglia di altezza auto, valgono tutte quanto la più alta:
     i sei blocchi diventano rettangoli identici, foto comprese. La quarta
     riga resta auto perché è una fascia, non uno dei rettangoli. */
  .features{
    display:grid; grid-template-columns:1fr 1fr;
    grid-template-rows:repeat(3, 1fr) auto;
  }
  .feature{ display:flex; flex-direction:column; justify-content:flex-start; }
  /* foto fuori dal calcolo dell'altezza: se contasse la loro altezza
     intrinseca sarebbero le immagini a dettare la riga, non i testi. */
  .feature-media{ position:relative; min-height:0; }
  .feature-media img{ position:absolute; inset:0; min-height:0; }
  .feature--social{ grid-column:1 / -1; order:3; }
  .feature-media--right{ order:2; }
  #ultimo-evento{ order:1; }
}

/* =============================================================================
   12 · CONTACT FORM
   ========================================================================== */
.contact-form{ padding:40px var(--edge) 64px; }
.contact-form form{ max-width:560px; }
.contact-form__note{
  font-size:var(--fs-body); color:var(--muted); line-height:var(--lh-text);
  margin-bottom:var(--space-md); max-width:var(--measure);
}

.field{ margin-bottom:var(--space-sm); }
.field label{
  display:block; font-size:var(--fs-micro); font-weight:700; letter-spacing:var(--ls-label);
  text-transform:uppercase; color:var(--muted); margin-bottom:var(--space-2xs);
}
.field input,
.field select,
.field textarea{
  display:block; width:100%; padding:14px 16px;
  font-family:var(--body); font-size:var(--fs-body); color:var(--black);
  background:var(--card); border:1px solid var(--line-dark); border-radius:8px;
  transition:border-color .2s var(--ease);
}
.field input:focus,
.field select:focus,
.field textarea:focus{ outline:none; border-color:var(--red); }
.field select{
  /* freccia disegnata da noi: quella di sistema si incolla al bordo destro e
     ignora il padding del campo. Con appearance:none il padding vale anche a
     destra e la punta resta staccata dal bordo come il testo a sinistra. */
  cursor:pointer; appearance:none; -webkit-appearance:none;
  padding-right:44px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%235c5b56' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 16px center;
}
.field textarea{ resize:vertical; min-height:130px; }
.field--honeypot{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

.contact-form__submit{ width:100%; margin-top:8px; }
.contact-form__submit[disabled]{ opacity:.6; cursor:default; }

.contact-form__sent,
.contact-form__error{
  display:none; margin-top:var(--space-sm); padding:14px 16px;
  border-radius:8px; font-size:var(--fs-note); color:var(--black);
}
.contact-form__sent{ background:var(--paper); }
.contact-form__error{ background:rgba(var(--red-rgb),.08); }
.contact-form__error a{ color:var(--red-ink); text-decoration:underline; }
.contact-form__sent.is-visible,
.contact-form__error.is-visible{ display:block; }

/* =============================================================================
   13 · REVEAL
   ========================================================================== */
.reveal{
  opacity:0; transform:translateY(24px);
  transition:opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-visible{ opacity:1; transform:translateY(0); }

/* =============================================================================
   14 · ARTICLE
   Two related things live here:
     · .article / .article__*  — the long narrative block (storia)
     · .article-*              — the news detail page building blocks
   ========================================================================== */
.article{ padding:var(--space-lg) var(--edge); }

.article__label{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  color:var(--red-ink); margin-bottom:var(--space-xs);
}
.article__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-title);
  line-height:var(--lh-display); margin-top:5px; margin-bottom:var(--space-sm);
}
.article__sign{
  font-size:var(--fs-note); letter-spacing:var(--ls-display); font-weight:600;
  color:var(--muted); margin-bottom:var(--space-sm);
}
.article__title + .article__sign{ margin-top:-16px; }

.article__body{ max-width:var(--measure-long); }
.article__body p{
  font-size:var(--fs-body); line-height:var(--lh-text); color:var(--ink);
  margin-bottom:var(--space-sm);
}

/* Intro block that carries a photo alongside it (dmc). The figure is last in
   the markup, so on a phone it lands where it reads best — after the text, just
   before the categories block. From 820px up it moves into its own column on
   the right, top-aligned with the label. */
/* Intro block carrying a photo (dmc). Same pieces, two arrangements:
     mobile   — text, quote and the Branch Manager note run full width, then a
                two-column row like the category grid: the photo line on the
                left, the photo on the right, running off the right page edge
     ≥820px   — text, note and quote down the left column, photo top-right
                inside the page margins with its caption underneath
   The photo line exists twice in the markup from one PHP string, because no
   rule can move a node from inside the figure into the text column. Exactly one
   of the two is displayed at any width, so nothing is announced or indexed
   twice. */
.article--split{
  display:grid; align-items:start;
  grid-template-columns:1fr 1fr;
  column-gap:var(--space-sm);
}
.article--split .article__main,
.article--split .quote,
.article--split .article__note{ grid-column:1 / -1; }
.article--split .article__photo-note{ grid-column:1; }
.article--split .article__aside{ grid-column:2; margin-right:calc(var(--edge) * -1); }

.article__aside img{ width:100%; height:auto; display:block; }
.article__aside figcaption{ display:none; }

/* Parallax frame, desktop only. The image is taller than the frame that crops
   it, and script.js writes --parallax as the section travels the viewport, so
   the photo drifts against the scroll. The 12% of image height it moves stays
   inside the 17.5% of headroom above and below, so no edge is ever exposed.
   Left at 0 the frame just shows the photo, which is what mobile and a reader
   with reduced motion get. */
@media (min-width:820px){
  .article__aside-media{ position:relative; overflow:hidden; aspect-ratio:3 / 4; }
  .article__aside-media img{
    position:absolute; left:0; top:-17.5%;
    width:100%; height:135%; object-fit:cover;
    transform:translateY(var(--parallax, 0%));
    will-change:transform;
  }
}
@media (prefers-reduced-motion:reduce){
  .article__aside-media img{ transform:none; }
}

@media (min-width:820px){
  /* .quote carries its own page margins, which would compound with the column
     it now sits in — at 834px that squeezed it to 162px wide. Inside this grid
     the column already provides the inset. */
  .article--split .quote{ margin-left:0; margin-right:0; }
  .article--split .article__aside{ margin-right:0; }

  .article__photo-note{ display:none; }
  .article__aside figcaption{
    display:block; margin-top:10px;
    font-size:var(--fs-note); color:var(--muted);
    line-height:var(--lh-snug);
  }
}

/* Tablet: a text column and a photo column side by side leaves the prose about
   290px wide, which is unreadable. So the article runs full width and only the
   Branch Manager note pairs off beside the photo. */
@media (min-width:820px) and (max-width:1199px){
  .article--split{ column-gap:var(--space-md); }
  .article--split .article__main,
  .article--split .quote{ grid-column:1 / -1; }
  .article--split .article__note{ grid-column:1; }
  .article--split .article__aside{ grid-column:2; }
}

/* Large desktop: prose down the left, photo top-right with its caption. */
@media (min-width:1200px){
  .article--split{
    grid-template-columns:minmax(0,1fr) minmax(240px,360px);
    column-gap:var(--space-lg);
  }
  .article--split .article__main{ grid-column:1; grid-row:1; }
  .article--split .article__note{ grid-column:1; grid-row:2; }
  .article--split .quote{ grid-column:1; grid-row:3; }
  .article--split .article__aside{ grid-column:2; grid-row:1; }
}

.article__more{ display:none; }
.article__more.is-open{ display:block; }
.article__toggle{
  background:none; border:none;
  display:inline-flex; align-items:center; min-height:var(--tap);
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); text-transform:uppercase;
  color:var(--black);
  padding:4px 0; margin-top:4px; cursor:pointer;
}
.article__toggle::after{ content:'→'; display:inline-block; margin-left:6px; transition:transform .25s var(--ease); }
.article__toggle:hover::after{ transform:translateX(5px); }
.article__toggle[aria-expanded="true"]::after{ content:'←'; }
.article__toggle[aria-expanded="true"]:hover::after{ transform:translateX(-5px); }

.pullquote{
  border-left:3px solid var(--red);
  padding:4px 0 4px 20px;
  margin:28px 0;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub);
  line-height:var(--lh-title); text-transform:uppercase;
}

@media (min-width:1200px){
  .article__title{ max-width:20ch; }
}

/* ---- news detail building blocks ---- */
/* news detail meta — lives inside the hero, right under the title, so it sits
   on the photo scrim and takes the light treatment rather than --muted */
.article-meta{
  display:flex; flex-wrap:wrap; align-items:center; gap:6px 20px;
  margin-bottom:var(--space-sm);
  font-size:var(--fs-note); letter-spacing:var(--ls-display);
  color:rgba(var(--white-rgb),.75);
}
/* the category pill sits next to the date; a byline, when there is one, trails both */
.article-meta__by{ order:1; }
/* second meta item (byline) hangs off an em dash — on phones it drops to its own line */
.article-meta__by::before{ content:'—'; margin-right:8px; }
@media (max-width:819px){
  .article-meta{ flex-direction:column; align-items:flex-start; gap:8px; }
  .article-meta__by::before{ content:none; }
}
.article-sub{
  font-family:var(--display); font-weight:var(--display-weight); text-transform:uppercase;
  font-size:var(--fs-sub);
  line-height:var(--lh-title); margin:var(--space-md) var(--edge) 12px; max-width:var(--measure-long);
}
.article-list{
  display:flex; flex-direction:column; gap:8px;
  margin:0 var(--edge) 18px; max-width:var(--measure-long);
}
.article-list li{
  font-size:var(--fs-body); line-height:var(--lh-snug);
  padding-left:18px; position:relative; color:var(--ink);
}
.article-list li::before{ content:'—'; position:absolute; left:0; color:var(--red); font-weight:700; }

/* links inside article prose need to be visible: the global reset strips them */
.article-copy a, .article-list a, .article__body a{
  color:var(--red-ink); text-decoration:underline; text-underline-offset:3px;
}
.article-copy a:hover, .article-list a:hover, .article__body a:hover{ color:var(--ink); }

.article-copy{ max-width:var(--measure-long); margin:0 var(--edge) 20px; }
.article-copy p{ font-size:var(--fs-body); line-height:var(--lh-text); color:var(--ink); margin-bottom:var(--space-xs); }
.article-copy p:last-child{ margin-bottom:0; }

.article-photo{ margin:8px var(--edge) var(--space-md); max-width:var(--measure-long); }
.article-photo img{ width:100%; display:block; border-radius:var(--radius); }
.article-photo--tall img{ max-height:480px; object-fit:cover; object-position:center 70%; }
.article-photo figcaption{ margin-top:8px; font-size:var(--fs-note); color:var(--muted); line-height:var(--lh-snug); }

/* Video dentro un articolo. La copertina è una facciata: il player di YouTube
   arriva solo se qualcuno preme play (js/script.js lo scambia al clic), così
   una notizia con tre video non ne scarica tre e chi non guarda non lascia
   niente a YouTube. Stesse misure e stessa didascalia di .article-photo. */
.article-video{ margin:8px var(--edge) var(--space-md); max-width:var(--measure-long); }
.article-video__play{
  position:relative; display:block; width:100%; padding:0; border:0;
  background:none; cursor:pointer; border-radius:var(--radius); overflow:hidden;
}
.article-video__play img,
.article-video iframe{ width:100%; aspect-ratio:16/9; display:block; border:0; border-radius:var(--radius); }
.article-video__play img{ object-fit:cover; }
.article-video__icon{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; }
.article-video__icon::before{
  content:''; width:52px; height:52px; border-radius:50%;
  background:var(--red); box-shadow:0 4px 18px rgba(0,0,0,.4);
  transition:background .25s var(--ease), transform .25s var(--ease);
}
.article-video__icon::after{
  content:''; position:absolute;
  border-style:solid; border-width:9px 0 9px 15px;
  border-color:transparent transparent transparent var(--white);
  margin-left:4px;
}
.article-video__play:hover .article-video__icon::before{ background:var(--black); transform:scale(1.08); }
.article-video__play:focus-visible{ outline:2px solid var(--red-ink); outline-offset:4px; }
.article-video figcaption{ margin-top:8px; font-size:var(--fs-note); color:var(--muted); line-height:var(--lh-snug); }

.quote{
  font-family:var(--body); font-weight:500;
  font-size:var(--fs-sub); line-height:var(--lh-snug); color:var(--ink);
  /* grey rule: the citation is quieter than the question, which takes the
     accent — that difference is how the two roles read apart */
  border-left:3px solid var(--line-dark); padding:2px 0 2px 20px;
  /* Adjacent siblings collapse their vertical margins and the larger one wins,
     so a quote between two blocks with different margins came out lopsided —
     22px above, 30px below. One step of the scale here, and the two neighbours
     that used to exceed it (.article-sub top, .article-photo bottom) brought
     onto the same step, so the gap is identical on both sides wherever a quote
     lands. */
  margin:var(--space-md) var(--edge); max-width:40.4rem;
}
/* On a phone the H3 size turned a two-line pull quote into nine lines that ate
   the whole screen. It drops to body size, where the 500 weight and the rule
   down its left side are what still mark it as a quote. */
@media (max-width:819px){
  .quote{ font-size:var(--fs-body); }
}

/* Interview questions used to borrow .quote, but a question introduces an
   answer — it is a heading, not a citation, and it was reading as a pull quote
   at H3 size. Same size as the answer it sits above, told apart by weight
   alone, and at every width: there is nothing responsive to trade off once the
   two are the same size. It keeps the accent rule, which is what marks where a
   new question starts as you scan the page. */
.article-question{
  font-family:var(--body); font-weight:700;
  font-size:var(--fs-body); line-height:var(--lh-snug); color:var(--ink);
  border-left:3px solid var(--red); padding:2px 0 2px 20px;
  margin:var(--space-md) var(--edge) var(--space-sm);
  max-width:var(--measure-long);
}
.quote cite{
  display:block; font-style:normal;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-micro); letter-spacing:var(--ls-label); text-transform:uppercase;
  color:var(--red-ink); margin-top:8px;
}
.article__body .quote{ margin-left:0; margin-right:0; max-width:none; }

.infobox{
  margin:8px var(--edge) 48px; padding:24px 22px;
  background:var(--paper); border-radius:var(--radius-lg); max-width:var(--measure-long);
}
.infobox__title{
  font-family:var(--display); font-weight:var(--display-weight); text-transform:uppercase;
  font-size:var(--fs-sub); margin-bottom:var(--space-xs);
}
.infobox__row{
  display:flex; gap:10px; font-size:var(--fs-note); padding:6px 0;
  border-top:1px solid var(--line-dark);
}
.infobox__row:first-of-type{ border-top:none; }
.infobox__row dt{ flex:none; width:120px; color:var(--muted); font-weight:700; }
.infobox__row dd{ color:var(--ink); }

.podium{
  display:flex; flex-direction:column; gap:10px;
  margin:0 var(--edge) 40px; max-width:var(--measure-long);
}
.podium__row{
  display:flex; align-items:baseline; gap:16px;
  padding:14px 18px; background:var(--white);
  border:1px solid var(--line-dark); border-radius:12px;
}
.podium__pos{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub); color:var(--red); flex:none; width:24px;
}
.podium__name{ font-size:var(--fs-body); font-weight:700; }

.article-nav{
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  margin-top:var(--space-lg); margin-bottom:0; padding:16px var(--edge);
  background:var(--red);
}
.article-nav__link{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); text-transform:uppercase;
  color:var(--white);
  transition:opacity .25s var(--ease);
}
.article-nav__link:hover{ opacity:.7; }
.article-nav__link--archive{ border-bottom:1px solid rgba(var(--white-rgb),.6); padding-bottom:2px; }
.article-nav__link--disabled{ opacity:.4; pointer-events:none; }

@media (min-width:1200px){
  .quote{ max-width:42.9rem; }
}

/* =============================================================================
   15 · STEPS · STATS · EQUIPMENT  (category regulation pages)
   ========================================================================== */
.section-title{
  font-family:var(--display); font-weight:var(--display-weight); text-transform:uppercase;
  font-size:var(--fs-title);
  padding:0 var(--edge); margin-bottom:var(--space-xs);
}
/* inside an already padded section the horizontal padding would double up */
.article > .section-title{ padding-left:0; padding-right:0; }

.steps{ padding:0 var(--edge) var(--space-lg); display:flex; flex-direction:column; }
.step{ display:flex; gap:20px; padding:28px 0; border-top:1px solid var(--line-dark); }
.step:last-child{ border-bottom:1px solid var(--line-dark); }
.step__num{
  flex:none; font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-title); color:var(--red); line-height:var(--lh-flat);
}
.step__name{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  color:var(--muted); margin-bottom:var(--space-2xs); text-transform:uppercase;
}
.step__title{
  font-family:var(--display); font-weight:var(--display-weight); text-transform:uppercase;
  font-size:var(--fs-sub); margin-bottom:var(--space-2xs);
}
.step__body p{ font-size:var(--fs-body); line-height:var(--lh-text); color:var(--ink-soft); margin-bottom:var(--space-2xs); }
.step__body p:last-child{ margin-bottom:0; }
.step__body b{ color:var(--black); }

.stats{ padding:0 var(--edge) var(--space-lg); display:flex; flex-wrap:wrap; gap:16px 32px; }
.stat{ flex:1 1 130px; }
.stat__num{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-title); line-height:var(--lh-flat); color:var(--black);
}
.stat__label{ font-size:var(--fs-note); color:var(--muted); margin-top:6px; line-height:var(--lh-snug); }
.stats__note{ width:100%; font-size:var(--fs-note); color:var(--red-ink); font-weight:700; margin-top:4px; }

.equip{
  margin:8px var(--edge) 48px; padding:24px 22px;
  background:var(--paper); border-radius:var(--radius-lg); max-width:var(--measure-long);
}
.equip > .section-title{ padding-left:0; padding-right:0; }
.equip__row{ display:flex; flex-direction:column; gap:24px; }
.equip__label{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  margin-bottom:var(--space-2xs); text-transform:uppercase;
}
.equip__col--yes .equip__label{ color:var(--red-ink); }
.equip__col--no .equip__label{ color:var(--muted); }
.equip__list{ display:flex; flex-direction:column; gap:8px; }
.equip__list li{ font-size:var(--fs-body); line-height:var(--lh-snug); padding-left:18px; position:relative; }
.equip__col--yes .equip__list li::before{ content:'+'; position:absolute; left:0; color:var(--red-ink); font-weight:700; }
.equip__col--no .equip__list li::before{ content:'–'; position:absolute; left:0; color:var(--muted); font-weight:700; }
.equip__note{
  display:flex; align-items:flex-start; gap:10px;
  font-size:var(--fs-body); color:var(--red-ink); font-weight:600; line-height:var(--lh-text);
  margin-top:var(--space-sm); padding:14px 16px;
  background:rgba(var(--red-rgb),.08); border-left:3px solid var(--red); border-radius:4px;
}
.equip__note svg{ flex:none; width:18px; height:18px; margin-top:2px; }
.equip__note svg circle{ fill:var(--red); }
.equip__note svg path{ fill:none; stroke:var(--white); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }

@media (min-width:820px){
  .equip__row{ flex-direction:row; }
  .equip__col{ flex:1; }
  .stat{ flex:0 1 160px; }
}

/* =============================================================================
   16 · GENERATIONS + VINYL SLIDER
   ========================================================================== */
.gens{ padding:var(--space-lg) 0; background:var(--paper); }
.gens__label,
.gens__title,
.gens__sub{ padding:0 var(--edge); }
/* Same kicker as .article__label, so "EVOLUZIONE" here reads as the next beat
   after "LE ORIGINI" in the article above. */
.gens__label{
  display:block;
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  color:var(--red-ink); margin-bottom:var(--space-2xs);
}
.gens__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-title);
  line-height:var(--lh-display); margin-bottom:var(--space-2xs);
}
.gens__sub{ color:var(--muted); font-size:var(--fs-body); max-width:var(--measure); margin-bottom:var(--space-lg); }
.gens__sub--lead{ margin-bottom:var(--space-xs); }
@media (min-width:820px){
  .gens__sub{ max-width:none; }
}

.vinyl-slider-outer{ position:relative; }
.vinyl-slider{
  display:flex;
  overflow-x:auto;
  scroll-snap-type:x mandatory;
  -webkit-overflow-scrolling:touch;
  scrollbar-width:none;
}
.vinyl-slider::-webkit-scrollbar{ display:none; }
.vinyl-slide{
  flex:0 0 100%;
  scroll-snap-align:center;
  display:flex; align-items:center; justify-content:center;
  padding:8px 32px;
}
.slide-inner{ position:relative; width:100%; max-width:420px; }
@media (min-width:1200px){
  .slide-inner{ max-width:460px; }
}

.slide-disc{ width:100%; height:auto; display:block; overflow:visible; }
.slide-disc-bg{ fill:var(--black); }
.slide-groove{ fill:none; stroke:rgba(var(--white-rgb),.16); stroke-width:1; }
.slide-label{ fill:var(--red); }
.slide-spindle{ fill:var(--black); stroke:var(--white); stroke-width:1.5; }
/* SVG text: sized in the disc's own 500×500 viewBox units, not CSS px — it
   scales with the artwork, so it is intentionally outside the type scale. */
.slide-label-num{
  fill:var(--white); text-anchor:middle;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:34px;
}
.slide-ring-text{
  fill:var(--white);
  font-family:var(--body); font-weight:700;
  letter-spacing:var(--ls-display); text-transform:uppercase;
}
.slide-ring-text .ring-sep{ fill:var(--red); }
.slide-rotor{
  transform-origin:250px 250px;
  transition:transform .8s var(--ease-menu);
}
.slide-caption{
  text-align:center; margin-top:var(--space-sm);
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-sub);
}

/* year cursor — a horizontal timeline under the vinyl slider; each stop is a
   generation, and the fill bar travels to the active stop as you swipe. */
.gens__cursor{ padding:0 var(--edge); margin-top:var(--space-sm); }
.gens__cursor-track{ position:relative; height:2px; background:var(--line-dark); margin:0 0 12px; }
.gens__cursor-fill{
  position:absolute; top:0; left:0; height:2px; width:0%;
  background:var(--red);
  transition:width .5s var(--ease);
}
.gens__cursor-stops{ display:flex; justify-content:space-between; }
.gens__cursor-stop{
  background:none; border:none;
  /* 44px tap target around a 8px dot + year label */
  padding:4px; min-width:var(--tap); min-height:var(--tap); margin:-4px;
  cursor:pointer;
  display:flex; flex-direction:column; align-items:center; gap:6px;
}
.gens__cursor-dot{
  width:8px; height:8px; border-radius:50%;
  background:var(--line-dark);
  transition:background .25s var(--ease), transform .25s var(--ease);
}
.gens__cursor-stop.is-active .gens__cursor-dot{ background:var(--red); transform:scale(1.35); }
.gens__cursor-year{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); color:var(--muted);
  transition:color .25s var(--ease);
}
.gens__cursor-stop.is-active .gens__cursor-year{ color:var(--red-ink); }

/* =============================================================================
   17 · ITALIAN BATTLES
   -----------------------------------------------------------------------------
   Pure white (--card), not the site ivory: the four logos are black artwork on
   a baked-in white background, so anything but #fff would show them as visible
   rectangles. Each battle is one row — logo, then name and copy — stacked on a
   phone and side by side from 768px up.

   The 768px switch is deliberate and local to this block: it is the only place
   on the site that needs a tablet in portrait (768px wide, below the site's
   820px breakpoint) to already read as desktop, because the stacked variant
   bleeds the logo to both page edges and that only makes sense on a phone.
   ========================================================================== */
.battles{ padding:var(--space-lg) var(--edge); background:var(--card); }
.battles__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-title);
  line-height:var(--lh-display); margin-bottom:var(--space-sm);
}
.battles__sub{
  color:var(--muted); font-size:var(--fs-body); line-height:var(--lh-text);
  max-width:var(--measure-long); margin-bottom:var(--space-md);
}
.battles__list{ display:flex; flex-direction:column; }
.battles__item{
  display:grid; gap:var(--space-sm);
  padding:var(--space-md) 0;
  border-top:1px solid var(--line-dark);
}
/* On a phone the logo runs edge to edge: the artwork is black on white and the
   section is white too, so the image bleeds off both page margins with no
   visible seam. From 768px up it sits back inside its own column. */
.battles__logo{
  width:calc(100% + var(--edge) * 2);
  max-width:none;              /* the global img{max-width:100%} would undo the bleed */
  margin-inline:calc(var(--edge) * -1);
  height:auto;
}
.battles__name{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-sub); line-height:var(--lh-title);
  margin-bottom:var(--space-2xs);
}
.battles__body p{
  font-size:var(--fs-body); line-height:var(--lh-text); color:var(--ink);
  margin-bottom:var(--space-xs);
}
.battles__body p:last-child{ margin-bottom:0; }

@media (min-width:768px){
  .battles__item{ grid-template-columns:260px 1fr; column-gap:var(--space-md); align-items:start; }
  .battles__logo{ width:100%; margin-inline:0; }
  .battles__text{ max-width:var(--measure-long); }
}

/* =============================================================================
   18 · CREWS
   ========================================================================== */
.crews{ padding:var(--space-lg) var(--edge); }
.crews__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-title); margin-bottom:var(--space-2xs);
}
.crews__sub{ color:var(--muted); font-size:var(--fs-body); max-width:var(--measure); margin-bottom:var(--space-md); }
.crews__list{ display:flex; flex-direction:column; border-top:1px solid var(--line-dark); }
.crews__item{
  position:relative; padding:16px 0 16px 20px;
  border-bottom:1px solid var(--line-dark);
  display:flex; flex-direction:column; align-items:flex-start; gap:4px;
}
.crews__item::before{
  content:''; position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:7px; height:7px; border-radius:50%; background:var(--red);
}
.crews__name{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub); line-height:var(--lh-title); text-transform:uppercase;
}
.crews__note{ font-size:var(--fs-note); color:var(--muted); }

@media (min-width:820px){
  .crews__list{ display:grid; grid-template-columns:1fr 1fr; column-gap:40px; }
  .crews__item{ flex-direction:row; align-items:baseline; flex-wrap:wrap; gap:2px 12px; }
}

/* =============================================================================
   19 · CLOSING
   ========================================================================== */
.closing{
  background:var(--black); color:var(--white);
  padding:var(--space-lg) var(--edge); text-align:center;
}
.closing--red{ background:var(--red); color:var(--white); }
.closing__text{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase;
  font-size:var(--fs-title);
  line-height:var(--lh-title); max-width:16ch; margin:0 auto 20px;
}
.closing__sign{
  color:var(--red); font-size:var(--fs-note); letter-spacing:var(--ls-eyebrow);
  font-weight:700; margin-bottom:var(--space-md);
}
.closing--red .closing__sign{ color:var(--black); }
.closing__cta{ display:flex; flex-wrap:wrap; justify-content:center; gap:12px; }

@media (min-width:1200px){
  .closing__text{ max-width:20ch; }
}

/* =============================================================================
   20 · CATEGORY CARDS
   ========================================================================== */
.cats{ padding:0 var(--edge) var(--space-lg); }
.cats__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; font-size:var(--fs-title);
  line-height:var(--lh-title); margin-bottom:var(--space-2xs);
}
.cats__sub{ font-size:var(--fs-body); color:var(--muted); margin-bottom:var(--space-sm); }

/* Two columns from mobile up — logo/text alternate per category so a full row
   of tall square logos never stacks and eats vertical space. */
.catgrid{
  display:grid; grid-template-columns:1fr 1fr;
  margin-left:calc(var(--edge) * -1); margin-right:calc(var(--edge) * -1);
}
.catgrid > *:nth-child(1){ order:1; }
.catgrid > *:nth-child(2){ order:2; }
.catgrid > *:nth-child(3){ order:4; }
.catgrid > *:nth-child(4){ order:3; }
.catgrid > *:nth-child(5){ order:5; }
.catgrid > *:nth-child(6){ order:6; }
.catgrid > *:nth-child(7){ order:8; }
.catgrid > *:nth-child(8){ order:7; }

.catgrid__logo{
  background:var(--paper);
  display:flex; align-items:center; justify-content:center;
  padding:16px; min-height:180px;
}
.catgrid__logo img{ width:96px; height:96px; object-fit:contain; transition:transform .5s var(--ease); }
.catgrid__logo:hover img{ transform:rotate(18deg) scale(1.08); }
/* Scratch and Open source art carries more internal padding than Classic /
   Supremacy, so at the same box size they read visibly smaller — sized up here
   to look consistent. Scratch = 3rd catgrid child, Open = 7th. */
.catgrid > *:nth-child(3) img,
.catgrid > *:nth-child(7) img{ width:132px; height:132px; }

.catgrid__info{ background:var(--card); padding:20px 16px; }
.catgrid__num{
  display:block; font-size:var(--fs-micro); letter-spacing:var(--ls-label); font-weight:700;
  text-transform:uppercase; color:var(--red-ink); margin-bottom:var(--space-2xs);
}
.catgrid__name{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; font-size:var(--fs-title);
  line-height:var(--lh-display); margin-bottom:var(--space-2xs);
}
.catgrid__tagline{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); text-transform:uppercase;
  color:var(--muted); margin-bottom:var(--space-2xs);
}
.catgrid__desc{ display:none; }
.catgrid__link{
  display:inline-flex; align-items:center; width:fit-content;
  min-height:var(--tap); margin-block:calc((var(--tap) - 1.4em) / -2);
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); color:var(--red-ink);
}
.catgrid__link::after{ content:'→'; display:inline-block; margin-left:6px; transition:transform .25s var(--ease); }
.catgrid__link:hover::after{ transform:translateX(5px); }

/* From tablet up the cards get room for a full description, so the mobile-only
   one-line tagline is swapped out for it. */
@media (min-width:820px){
  .catgrid{ margin-left:0; margin-right:0; }
  .catgrid__logo{ min-height:240px; padding:28px; }
  .catgrid__logo img{ width:140px; height:140px; }
  .catgrid > *:nth-child(3) img,
  .catgrid > *:nth-child(7) img{ width:190px; height:190px; }
  .catgrid__info{ padding:32px 28px; }
  .catgrid__num{ letter-spacing:var(--ls-eyebrow); margin-bottom:var(--space-xs); }
  .catgrid__name{ margin-bottom:var(--space-xs); }
  .catgrid__tagline{ display:none; }
  .catgrid__desc{
    display:block; font-size:var(--fs-body); line-height:var(--lh-text);
    margin-bottom:var(--space-sm); max-width:var(--measure);
  }
}

/* =============================================================================
   21 · NEWS LIST + CATEGORY FILTER
   -----------------------------------------------------------------------------
   The filter hides cards client-side rather than reloading the page, so every
   article stays in the markup: with JS off the whole list is simply visible,
   which is the right thing to fall back to. js/script.js owns the toggling.
   ========================================================================== */
/* -- the control, mobile-first -------------------------------------------
   On a phone only the FILTRA trigger shows; the row of categories takes over
   from 820px, where there is room to lay them out in full. Whichever is not in
   use is display:none, so exactly one set of buttons is in the accessibility
   tree at any width. No pills: the design system has none, so the categories
   are set as type with a rule and a red marker for the active one. */
.news-filter{
  display:flex; align-items:center; flex-wrap:wrap; gap:10px 20px;
  padding:40px var(--edge) 0;
}
.news-filter__label{
  display:none;                       /* the trigger carries the word on mobile */
  align-items:center; gap:8px;
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  text-transform:uppercase; color:var(--red-ink);
}
.news-filter__icon{ flex:none; }
.news-filter__options{ display:none; }

.news-filter__trigger{
  display:inline-flex; align-items:center; gap:10px;
  min-height:var(--tap); padding:0;
  border:none; background:none; color:var(--red-ink); cursor:pointer;
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  text-transform:uppercase;
}
.news-filter__trigger-value{
  color:var(--ink); letter-spacing:var(--ls-label);
  /* Underline drawn by text-decoration, not by a border: a border plus its
     padding made this box 3px taller than the word beside it, and centring the
     row then lifted the value 1.5px off the label's baseline. A decoration
     does not touch the box, so the two sit on the same line. */
  text-decoration:underline;
  text-decoration-color:var(--line-dark);
  text-decoration-thickness:1px;
  text-underline-offset:4px;
}

/* -- the desktop category buttons ---------------------------------------- */
/* Pills, not bare type. As plain small text the categories were unreadable:
   Big Shoulders is condensed and closes up below ~14px, and with nothing
   around each label the row read as one run-on line. The border gives each
   category its own shape, and the body face holds at this size. */
.news-filter__opt{
  display:inline-flex; align-items:center;
  min-height:var(--tap); padding:0 18px;
  border:1px solid var(--line-dark); border-radius:100px;
  background:none; color:var(--ink); cursor:pointer;
  font-family:var(--body); font-weight:700;
  font-size:calc(var(--fs-tagline) - 4px);   /* 11px here; see the note above */
  letter-spacing:var(--ls-label); text-transform:uppercase;
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.news-filter__opt:hover{ border-color:var(--black); }
.news-filter__opt.is-active{ background:var(--black); border-color:var(--black); color:var(--white); }

/* -- bottom sheet, mobile only ------------------------------------------- */
.news-sheet{
  position:fixed; inset:0; z-index:60;
  visibility:hidden;
  transition:visibility 0s linear .32s;   /* stay visible until the slide-out ends */
}
.news-sheet.is-open{ visibility:visible; transition-delay:0s; }
.news-sheet__backdrop{
  position:absolute; inset:0;
  background:rgba(var(--black-rgb),.45);
  opacity:0; transition:opacity .28s var(--ease);
}
.news-sheet.is-open .news-sheet__backdrop{ opacity:1; }
.news-sheet__panel{
  position:absolute; left:0; right:0; bottom:0;
  background:var(--white);
  border-radius:var(--radius-lg) var(--radius-lg) 0 0;
  padding:10px var(--edge) max(var(--space-md), env(safe-area-inset-bottom));
  transform:translateY(100%);
  transition:transform .32s var(--ease);
  will-change:transform;
}
.news-sheet.is-open .news-sheet__panel{ transform:translateY(0); }
.news-sheet__panel.is-dragging{ transition:none; }   /* follow the finger 1:1 */
.news-sheet__grip{
  display:block; width:38px; height:4px; border-radius:100px;
  background:var(--line-dark); margin:0 auto var(--space-sm);
}
.news-sheet__title{
  font-size:var(--fs-micro); letter-spacing:var(--ls-eyebrow); font-weight:700;
  text-transform:uppercase; color:var(--red-ink);
  margin-bottom:var(--space-2xs);
}
.news-sheet__list{ display:flex; flex-direction:column; }
/* One line of type per category, a hairline between them and a whole row to
   aim at — 64px is comfortably past the 44px minimum for a thumb. */
.news-sheet__opt{
  display:flex; align-items:center;
  min-height:64px; padding:0;
  border:none; border-top:1px solid var(--line-dark); background:none;
  text-align:left; cursor:pointer;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub); line-height:var(--lh-title); text-transform:uppercase;
  color:var(--ink);
}
.news-sheet__opt.is-active{ color:var(--red-ink); }
.news-sheet__opt.is-active::after{
  content:''; width:8px; height:8px; border-radius:50%;
  background:var(--red); margin-left:auto;
}

@media (prefers-reduced-motion:reduce){
  .news-sheet,
  .news-sheet__panel,
  .news-sheet__backdrop{ transition-duration:.01ms; }
}

@media (min-width:820px){
  .news-filter__label{ display:inline-flex; }
  .news-filter__options{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
  .news-filter__trigger,
  .news-sheet{ display:none; }
}

.news-list{ padding:40px var(--edge) 64px; display:flex; flex-direction:column; }
.news-filter + .news-list{ padding-top:var(--space-sm); }
.news-card{
  display:flex; flex-direction:column; gap:10px;
  /* --space-md on each side of the hairline: the gap between two articles is
     what separates them, and it has to beat the 10px gap inside a card by
     enough that the card reads as one block */
  padding:var(--space-md) 0; border-bottom:1px solid var(--line-dark);
  transition:transform .3s var(--ease);
}
/* .news-card is display:flex, so [hidden] alone would not hide it */
.news-card[hidden]{ display:none; }
/* :last-child covers the unfiltered list; once a filter runs the last card on
   screen is no longer the last in the DOM, so the script marks it instead */
.news-list .news-card:last-child,
.news-list .news-card.is-last{ border-bottom:none; }
.news-card:hover{ transform:translateX(8px); }
.news-card__meta{ display:flex; align-items:center; gap:10px; }
.news-card__date{ font-size:var(--fs-micro); letter-spacing:var(--ls-label); color:var(--muted); }
/* --fs-micro is the floor for anything carrying meaning, so the pill is kept
   compact with weight, line-height and padding instead of a smaller type size.
   The other micro labels are 700 because they have to hold their own against
   the page; this one sits on a filled pill that already does that, so it drops
   to 500 and stops shouting next to the date it sits beside. */
/* Stessa etichetta del pannello di redazione: rettangolo appena stondato, non
   maiuscoletto spaziato. Il nome della sezione è un dato, come la data che gli
   sta accanto — non un titolo da annunciare — e in minuscolo si legge in un
   colpo d'occhio invece che lettera per lettera. La riga meta è allineata al
   centro, quindi la pillola può essere più alta della data senza sfalsarla. */
.news-card__badge{
  font-family:var(--ui); font-size:var(--fs-micro); font-weight:500;
  color:var(--white); padding:2px 8px; border-radius:5px; line-height:1.55;
  background:var(--grey);
}
.news-card__badge--dmc{ background:var(--black); }
.news-card__badge--kcs{ background:var(--red); }
/* Seconda etichetta: dice cos'altro è quella notizia, quindi sta un gradino
   sotto a quella della sezione e non ne prende il colore. */
.news-card__badge--gallery{
  background:transparent; border:1px solid var(--line-dark); color:var(--muted);
  padding:1px 7px;
}
.article-meta .news-card__badge--gallery{ border-color:var(--line); color:var(--white); }
/* in the hero the pill sits on a dark photo scrim, where the black DMC variant
   disappears — invert it there, the other two already read fine */
.article-meta .news-card__badge--dmc{ background:var(--white); color:var(--black); }
/* Photo count — only printed on posts that carry a gallery, so it doubles as
   the marker that says "there are pictures in here" without a second badge. */
.news-card__photos{
  display:inline-flex; align-items:center; gap:5px;
  font-size:var(--fs-micro); letter-spacing:var(--ls-label); color:var(--muted);
}
.news-card__photos svg{
  flex:none; fill:none; stroke:currentColor; stroke-width:1.3;
  stroke-linecap:round; stroke-linejoin:round;
}
.news-card__title{
  font-family:var(--display); font-weight:var(--display-weight); text-transform:uppercase;
  font-size:var(--fs-sub); line-height:var(--lh-title);
  transition:color .3s var(--ease);
}
.news-card:hover .news-card__title{ color:var(--red); }
.news-card__excerpt{ font-size:var(--fs-note); color:var(--muted); line-height:var(--lh-text); }
.news-card__link{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-label); color:var(--red-ink);
}

/* Paging control under the list. The script hides it as soon as the filtered
   set is fully on screen, so the count only ever reads while there is more. */
.news-more{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-2xs);
  padding:0 var(--edge) var(--space-lg);
}
.news-more[hidden]{ display:none; }
.news-more__count{
  font-size:var(--fs-note); letter-spacing:var(--ls-label); color:var(--muted);
}
/* the card the script moves focus to after "carica altre" */
.news-card:focus-visible{ outline:2px solid var(--red-ink); outline-offset:6px; }

/* Draft banner on an unpublished article, visible only to a logged-in editor. */
.draft-flag{
  background:var(--red); color:var(--white); text-align:center;
  font-size:var(--fs-note); letter-spacing:var(--ls-label);
  padding:12px var(--edge);
}
.draft-flag a{ color:var(--white); text-decoration:underline; }

/* =============================================================================
   22 · HONOR ROLL
   Symmetric two-column timeline: spine at the true centre, years left / names
   right on every row. Used by both dmc.php and kcs.php.

   ⚠ .honor__year and .honor__name must keep IDENTICAL font-size and
   line-height. The row dot (.honor__row::after) is positioned at half a line
   box down from the row's top padding, derived from those tokens with calc(),
   and js/script.js measures the same computed value to place the travelling
   dot. Change one of the two and the dot silently drifts off the name.
   ========================================================================== */
.honor{ padding:0 var(--edge) var(--space-lg); }
.honor__title{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; font-size:var(--fs-title);
  margin-top:var(--space-sm); margin-bottom:var(--space-2xs);
  text-align:center;
}
.honor__sub{
  color:var(--muted); font-size:var(--fs-body); max-width:var(--measure);
  margin:0 auto 24px; text-align:center;
}

.honor__list{
  position:relative; max-width:600px; margin:40px auto 0;
  display:grid; grid-template-columns:1fr 1fr; column-gap:0;
}
.honor__list::before{
  /* The spine spans exactly from the first row's dot to the last row's dot, no
     overshoot. top/bottom are set from JS (positionHonorSpine in script.js),
     which measures the actual dot positions — row heights vary a lot now that
     some rows carry a video preview and others don't, so a fixed px guess
     can't track every row correctly. */
  content:''; position:absolute; left:50%;
  top:var(--spine-top, 18px); bottom:var(--spine-bottom, 18px);
  width:2px; background:rgba(var(--black-rgb),.35); transform:translateX(-1px);
}

.honor__row{
  position:relative; grid-column:1 / -1;
  display:grid; grid-template-columns:1fr 1fr; column-gap:0; align-items:start;
  padding:30px 0 14px;
}
.honor__row::after{
  /* Anchored to the name line's vertical centre: the row's own top padding plus
     half a line box. Derived from the token with calc() rather than hand-tuned,
     so it keeps tracking --fs-sub if the scale ever moves. Year and name must
     share both font-size AND line-height for this to hold — see below. */
  content:''; position:absolute; left:50%;
  top:calc(30px + var(--fs-sub) * var(--lh-title) / 2);
  transform:translate(-50%,-50%);
  width:9px; height:9px; border-radius:50%; background:var(--red);
  box-shadow:0 0 0 2px var(--white); z-index:1;
}

.honor__year{
  /* Taken out of grid flow entirely: .honor__year's font can run much taller
     than a single-line .honor__info, and a grid track sizes to its tallest
     item regardless of align-items — left in flow, that extra height pushed
     .honor__videos down further than intended. Absolutely positioned over the
     same visual spot, it no longer affects the row's height. */
  position:absolute; top:30px; left:0; width:50%; padding-right:16px;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub);
  color:var(--red); text-align:right; line-height:var(--lh-title);
}
.honor__info{ grid-column:2; padding-left:16px; display:flex; flex-direction:column; gap:3px; }
.honor__name,
.honor__place-name{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; letter-spacing:var(--ls-display);
  /* size AND line-height must stay identical to .honor__year — the row dot is
     positioned from exactly this line box */
  font-size:var(--fs-sub); line-height:var(--lh-title);
}
.honor__note,
.honor__edition,
.honor__place-note{ color:var(--muted); font-size:var(--fs-note); }
.honor__edition{ text-transform:uppercase; letter-spacing:var(--ls-display); }
.honor__edition::before{ content:'— '; }
.honor__place{ display:block; }
.honor__place-num{ color:var(--muted); font-size:var(--fs-note); font-weight:700; margin-right:4px; }

/* Every other row mirrors across the spine — names left, year right. Without it
   the whole column of names hangs off the right side and the page reads
   lopsided, which is worst on phones where the two halves are narrowest.
   The flip is marked up server-side, not with :nth-child: js/script.js inserts
   the travelling dot as .honor__list's first child, which would flip the
   parity of every row the moment the script runs. */
.honor__row--flip .honor__year{
  left:auto; right:0; padding-right:0; padding-left:16px; text-align:left;
}
.honor__row--flip .honor__info{
  grid-column:1; padding-left:0; padding-right:16px; text-align:right;
}
.honor__row--flip .honor__place{
  display:flex; flex-direction:row-reverse; justify-content:flex-start;
  align-items:baseline; gap:4px;
}
.honor__row--flip .honor__place-num{ margin-right:0; }
/* the edition dash points at the spine on both sides — except the special
   mention, which keeps the leading dash whichever side it lands on */
.honor__row--flip .honor__edition::before{ content:none; }
.honor__row--flip .honor__edition::after{ content:' —'; }
.honor__row--flip .honor__edition--mention::before{ content:'— '; }
.honor__row--flip .honor__edition--mention::after{ content:none; }
.honor__place-note{ margin-left:4px; }
.honor__judges{ display:block; margin-top:5px; font-size:var(--fs-body); font-weight:400; color:var(--black); }
.honor__judges b{ font-weight:700; }

.honor__videos{
  /* margin-top is double the row's own padding (14px above + 14px below, the
     gap a name/year block sees between one video's bottom and the next row's
     padding before its own text starts) — matching it here means that
     gap-before-name and gap-after-name are equal, so the name sits vertically
     centred in the space between two consecutive videos */
  grid-column:1 / -1;
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:12px; margin-top:var(--space-md);
}
.honor__video-thumb{
  position:relative; display:block;
  width:100%; max-width:280px; aspect-ratio:16/9;
  border-radius:var(--radius); overflow:hidden;
  background:var(--black); border:none; padding:0; cursor:pointer;
}
.honor__video-thumb img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .5s var(--ease);
}
.honor__video-thumb:hover img{ transform:scale(1.06); }
.honor__video-play{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; }
.honor__video-play::before{
  content:''; width:52px; height:52px; border-radius:50%;
  background:var(--red); box-shadow:0 4px 18px rgba(0,0,0,.4);
  transition:background .25s var(--ease), transform .25s var(--ease);
}
.honor__video-play::after{
  content:''; position:absolute;
  border-style:solid; border-width:9px 0 9px 15px;
  border-color:transparent transparent transparent var(--white);
  margin-left:4px;
}
.honor__video-thumb:hover .honor__video-play::before{ background:var(--black); transform:scale(1.08); }

/* Scroll-driven dot: inserted as .honor__list's first child so it paints
   behind every row's content (same as the spine ::before) — travels behind the
   video previews as you scroll, never on top of them. */
.honor__scroll-dot{
  --pull:0;
  position:absolute; left:50%; top:0;
  width:9px; height:9px; margin:-4.5px 0 0 -4.5px;
  border-radius:50%; background:var(--red);
  box-shadow:0 0 0 2px var(--white),
             0 0 calc(10px + var(--pull) * 6px) 2px rgba(var(--red-rgb), calc(.55 + var(--pull) * .35));
  opacity:0; transform:scale(calc(1 + var(--pull) * .6));
  transition:opacity .3s var(--ease), top .08s ease-out;
  pointer-events:none;
}
.honor__scroll-dot.is-active{ opacity:1; }
.honor__row.is-pulse::after{ animation:honorDotPulse .5s var(--ease); }
@keyframes honorDotPulse{
  0%, 100%{ transform:translate(-50%,-50%) scale(1); }
  40%{
    transform:translate(-50%,-50%) scale(1.4);
    box-shadow:0 0 0 5px var(--white), 0 0 8px 2px rgba(var(--red-rgb),.6);
  }
}

@media (min-width:820px){
  /* symmetric halves so the spine sits at the true centre, 40px clear of the
     text on each side */
  .honor__list{ max-width:720px; }
  .honor__list::before{ top:var(--spine-top, 22px); bottom:var(--spine-bottom, 22px); }
  .honor__row{ padding:30px 0 20px; }
  .honor__row::after{ top:calc(30px + var(--fs-sub) * var(--lh-title) / 2); }
  .honor__year{ top:30px; padding-right:40px; }
  .honor__info{ padding-left:40px; display:block; }
  .honor__row--flip .honor__year{ padding-right:0; padding-left:40px; }
  .honor__row--flip .honor__info{ padding-left:0; padding-right:40px; }
  .honor__name{ display:inline-block; margin-right:12px; vertical-align:middle; }
  .honor__note,
  .honor__edition,
  .honor__judges,
  .honor__place{ display:block; }
  .honor__videos{ margin-top:var(--space-md); }
  .honor__video-thumb{ max-width:460px; }
}

/* =============================================================================
   23 · VIDEO LIGHTBOX
   ========================================================================== */
.lightbox{
  position:fixed; inset:0; z-index:200;
  display:flex; align-items:center; justify-content:center;
  opacity:0; visibility:hidden;
  transition:opacity .3s var(--ease), visibility 0s linear .3s;
}
.lightbox.is-open{ opacity:1; visibility:visible; transition:opacity .3s var(--ease); }
.lightbox__backdrop{
  position:absolute; inset:0;
  background:rgba(var(--black-rgb),.92);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
}
.lightbox__inner{ position:relative; z-index:1; width:100%; max-width:960px; padding:0 20px; }
.lightbox__close{
  position:absolute; top:-16px; right:16px; z-index:2;
  display:flex; align-items:center; justify-content:center;
  width:36px; height:36px; border-radius:50%; border:none;
  background:rgba(var(--white-rgb),.14); color:var(--white);
  cursor:pointer;
  transition:background .2s var(--ease);
}
.lightbox__close svg{
  width:16px; height:16px;
  fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round;
}
.lightbox__close:hover{ background:var(--red); }
.lightbox__logo{ display:block; height:22px; width:auto; margin:0 auto 18px; }
.lightbox__frame{
  position:relative; width:100%; aspect-ratio:16/9;
  background:var(--black); border-radius:var(--radius); overflow:hidden;
}
.lightbox__frame iframe{ position:absolute; inset:0; width:100%; height:100%; border:none; }
.lightbox__footer{
  display:flex; align-items:center; justify-content:center;
  gap:14px; margin-top:var(--space-sm);
}
.lightbox__nav{
  flex:none; z-index:2;
  width:36px; height:36px; border-radius:50%; border:none;
  background:rgba(var(--white-rgb),.14); color:var(--white);
  font-size:var(--fs-body); line-height:var(--lh-flat); cursor:pointer;
  transition:background .2s var(--ease), transform .2s var(--ease);
}
.lightbox__nav:hover{ background:var(--red); }
.lightbox__caption{ text-align:center; display:flex; flex-direction:column; gap:2px; }
.lightbox__caption-year{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-sub); line-height:var(--lh-flat); color:var(--red);
}
.lightbox__caption-name{
  font-family:var(--display); font-weight:var(--display-weight);
  text-transform:uppercase; letter-spacing:var(--ls-display);
  font-size:var(--fs-tagline); color:var(--white);
}

/* ---- lightbox video: il video a sinistra, la scheda dell'anno a destra ----
   La navigazione qui non sta ai lati del video ma sotto al nome, quindi i due
   tondi diventano due parole con un filo in mezzo. Tutto è confinato a
   .lightbox--video: la lightbox delle foto continua a usare la stessa scocca
   impaginata in colonna. */
.lightbox--video .lightbox__meta{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  margin-top:var(--space-sm);
}
.lightbox--video .lightbox__logo{ margin:0 0 var(--space-sm); opacity:.4; }
.lightbox--video .lightbox__caption-year{ font-size:var(--fs-hero); }
.lightbox--video .lightbox__caption{ gap:var(--space-2xs); }
.lightbox--video .lightbox__caption-name{ font-size:var(--fs-sub); }
.lightbox--video .lightbox__footer{ width:100%; max-width:260px; gap:14px; }
.lightbox--video .lightbox__nav{
  /* la parola resta alta 44px come richiede il tocco, ma senza tondo attorno */
  display:inline-flex; align-items:center; min-height:var(--tap);
  width:auto; height:auto; padding:0; border-radius:0; background:none;
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-note); letter-spacing:var(--ls-label); text-transform:uppercase;
  color:var(--white);
}
.lightbox--video .lightbox__nav:hover{ background:none; color:var(--red); }
.lightbox--video .lightbox__nav-rule{
  flex:1 1 auto; height:1px; background:rgba(var(--white-rgb),.35);
}

@media (min-width:820px){
  .lightbox__inner{ max-width:1040px; padding:0 40px; }
  .lightbox__logo{ height:28px; margin-bottom:var(--space-sm); }
  .lightbox__nav{ width:44px; height:44px; }
  .lightbox__footer{ gap:22px; margin-top:var(--space-sm); }

  .lightbox--video .lightbox__inner{
    display:grid; grid-template-columns:minmax(0,2fr) minmax(240px,1fr);
    align-items:center; gap:var(--space-lg); max-width:min(1400px, 94vw);
  }
  .lightbox--video .lightbox__meta{ margin-top:0; }
  .lightbox--video .lightbox__nav{ width:auto; height:auto; }
  /* la X torna all'angolo della finestra: con due colonne il bordo alto
     dell'impaginato non è più il bordo del video */
  .lightbox--video .lightbox__close{ position:fixed; top:24px; right:28px; }
  .lightbox--video .lightbox__footer{ margin-top:var(--space-md); }
}

/* =============================================================================
   24 · NEWS GALLERY + PHOTO LIGHTBOX
   ========================================================================== */
/* Masonry without JS: CSS columns, so tiles keep their own aspect ratio and
   the gaps close themselves. Reading order runs down a column, not across —
   fine for a photo set, which has no sequence to break. Two columns on mobile,
   three from 820px, four from 1200px. */
.gallery{ margin:var(--space-md) var(--edge) var(--space-lg); }
.gallery__intro{
  max-width:var(--measure-long);
  font-size:var(--fs-note); color:var(--muted); line-height:var(--lh-text);
  margin-bottom:var(--space-sm);
}
.gallery__grid{ column-count:2; column-gap:10px; }

.gallery__item{
  display:block; position:relative;
  width:100%; margin:0 0 10px; padding:0;
  border:none; background:none; cursor:zoom-in;
  border-radius:var(--radius); overflow:hidden;
  break-inside:avoid;           /* a tile is never split across two columns */
  -webkit-column-break-inside:avoid;
  line-height:0;                /* kills the inline-image gap under the photo */
}
.gallery__item img{
  width:100%; height:auto; display:block;
  transition:transform .5s var(--ease), filter .3s var(--ease);
}
.gallery__item:hover img,
.gallery__item:focus-visible img{ transform:scale(1.04); filter:brightness(.82); }

/* The magnifier and the caption are the hover state: both ride in from the
   edges, both stay hidden until then, so the grid itself reads as photos only. */
.gallery__zoom{
  position:absolute; top:10px; right:10px;
  display:flex; align-items:center; justify-content:center;
  width:32px; height:32px; border-radius:50%;
  background:rgba(var(--black-rgb),.55); color:var(--white);
  opacity:0; transform:scale(.8);
  transition:opacity .25s var(--ease), transform .25s var(--ease);
}
.gallery__zoom svg{
  width:15px; height:15px;
  fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round;
}
.gallery__caption{
  position:absolute; left:0; right:0; bottom:0;
  padding:22px 12px 10px;
  background:linear-gradient(to top, rgba(var(--black-rgb),.82), transparent);
  color:var(--white); text-align:left;
  font-size:var(--fs-micro); line-height:var(--lh-snug); letter-spacing:var(--ls-label);
  opacity:0; transform:translateY(6px);
  transition:opacity .25s var(--ease), transform .25s var(--ease);
}
.gallery__item:hover .gallery__zoom,
.gallery__item:focus-visible .gallery__zoom,
.gallery__item:hover .gallery__caption,
.gallery__item:focus-visible .gallery__caption{ opacity:1; transform:none; }

.gallery__credit{
  margin-top:14px;
  font-size:var(--fs-micro); letter-spacing:var(--ls-label); color:var(--muted);
}

/* Touch devices have no hover to reveal them with, so the caption is simply
   always on and the magnifier steps aside. */
@media (hover:none){
  .gallery__zoom{ display:none; }
  .gallery__caption{ opacity:1; transform:none; }
}

@media (min-width:820px){
  .gallery__grid{ column-count:3; column-gap:14px; }
  .gallery__item{ margin-bottom:14px; }
}
@media (min-width:1200px){
  .gallery__grid{ column-count:4; }
}

/* ---- photo lightbox — same shell as the video one, different frame ---- */
.lightbox--photo .lightbox__inner{ max-width:min(1200px, 100%); }
.lightbox__photo{
  display:flex; align-items:center; justify-content:center;
  /* Leave room for the close button above and the footer below, so a tall
     photo is never cropped and never pushes the caption off-screen. */
  height:min(76vh, 900px);
}
.lightbox__photo img{
  max-width:100%; max-height:100%;
  width:auto; height:auto;
  object-fit:contain;
  border-radius:var(--radius);
  opacity:0; transition:opacity .25s var(--ease);
}
.lightbox__photo img.is-loaded{ opacity:1; }
.lightbox--photo .lightbox__caption{ min-width:0; }
.lightbox__counter{
  font-family:var(--display); font-weight:var(--display-weight);
  font-size:var(--fs-tagline); letter-spacing:var(--ls-display); color:var(--red);
}
.lightbox__caption-text{
  font-size:var(--fs-note); line-height:var(--lh-snug); color:var(--white);
  max-width:60ch;
}

@media (min-width:820px){
  .lightbox__photo{ height:min(78vh, 940px); }
}
