/* nwdesigns — Design System NW 2026, campaign layer.

   Source of truth: Figma "designsystem _source_2026", page "Design System def NW"
   (file 3WmBgmZyTECpTR2gmaqImE), board "Design System NW · 2026 · tavola unica"
   (node 6234:777) and section "Visual signage" (node 6175:8). Where Figma and the
   main site disagree, Figma wins.

   This file is a layer on top of main.css, not a replacement: main.css keeps the
   page contract (grid, sections, form, footer) and this file swaps the tokens,
   the type system and the hero. It applies only under `body.ds-2026`, so a page
   opts in by adding the class and linking this sheet after main.css. Pages that
   do not opt in render exactly as before. */

/* ---- Self-hosted type ----------------------------------------------------
   Mulish (body) and Archivo at normal width (labels, owner 2026-10-22; was
   Space Mono) are served from this origin, as the
   main site serves them through next/font: no request reaches Google, so no
   visitor IP leaves the EU before consent. Titles use Archivo, the substitute
   the Figma board names for Aktiv Grotesk Extended (variable "Sostituto/Titoli":
   Archivo Regular). Owner ruling 2026-10-18: the Adobe kit was the slowest
   request on a phone and blocked the first paint, so 2026 pages serve Archivo
   from this origin instead. Owner, 2026-10-18: the Expanded cut (width axis at
   125%), the closest to the extended face it stands in for — fixed with
   fontTools' instancer at wdth 125 and weights 400–700 (31.2 KB latin instead
   of the 90 KB variable file).
   All three are SIL OFL 1.1 — licences sit beside the files. */
@font-face {
  font-family: "Archivo Expanded";
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/_shared/fonts/archivo-latin-expanded-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo Expanded";
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/_shared/fonts/archivo-latin-ext-expanded-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Mulish";
  font-style: normal;
  font-display: swap;
  font-weight: 200 1000;
  src: url("/_shared/fonts/mulish-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Mulish";
  font-style: normal;
  font-display: swap;
  font-weight: 200 1000;
  src: url("/_shared/fonts/mulish-latin-ext-wght-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url("/_shared/fonts/archivo-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url("/_shared/fonts/archivo-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---- Tokens ----------------------------------------------------------------
   Figma variables, mapped onto the names main.css already reads. The neutral
   ramp is unchanged in value (main.css counts it from 100, Figma from 50). */
.ds-2026 {
  /* brand/red — one red for UI and logo since the 2026 board. */
  --nw-primary: #e21518;
  --nw-accent: #e21518;
  --nw-accent-hover: #c4121a; /* brand/red-hover */
  --nw-accent-pressed: #a00f15; /* brand/red-pressed */
  /* brand/near-black "Noir Black": headline ink and dark bands alike. */
  --nw-schwarz: #2b2b2b;
  --nw-foreground: #2b2b2b; /* text/primary */
  --nw-foreground-secondary: #575757; /* text/secondary */
  --nw-muted: #575757;
  --nw-border: #e1e1e1; /* border/default */
  --nw-border-strong: #828282; /* border/strong */

  /* Small red text (labels, indexes) steps down to the hover red: #e21518 on
     Egg Shell is about 4.5:1, right on the AA line; #c4121a clears it. */
  --nw-red-text: #c4121a;

  --font-display: "Archivo Expanded", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Mulish", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Owner 2026-10-22: labels move from Space Mono to Archivo at normal width. */
  --font-label: "Archivo", "Helvetica Neue", Arial, sans-serif;

  font-family: var(--font-body);
  font-size: 1rem; /* Testo/Corpo: Mulish 16/28 */
  line-height: 1.75;
}

@media (min-width: 1024px) {
  .ds-2026 {
    font-size: 1.0625rem;
  }
}

/* ---- Type roles ----------------------------------------------------------- */

/* Titles in Archivo (Figma's substitute for Aktiv Grotesk Extended); everything
   that reads stays in Mulish. */
.ds-2026 h1,
.ds-2026 h2,
.ds-2026 h3,
.ds-2026 .tension-statement,
.ds-2026 .faq-item summary,
.ds-2026 .marquee-track,
.ds-2026 .figures,
.ds-2026 .brand-mark {
  font-family: var(--font-display);
}

/* Label — Archivo Regular 14/22 at normal width (owner 2026-10-22, was Space
   Mono). Uppercase as on the board's meta lines, opened up a little. */
.ds-2026 .eyebrow,
.ds-2026 .item-index,
.ds-2026 .required-note,
.ds-2026 .hero-media figcaption,
.ds-2026 .story-media figcaption {
  font-family: var(--font-label);
  font-weight: 400;
  letter-spacing: 0;
}

/* Archivo is narrower than the mono it replaces: uppercase labels get a
   little tracking so they keep reading as labels, not as small headings. */
.ds-2026 :is(.eyebrow, .faq-group-title, .review-source, .sector-case-meta) {
  letter-spacing: 0.04em;
}

.ds-2026 .eyebrow {
  margin-bottom: 20px;
  color: var(--nw-red-text);
  font-size: 0.875rem;
  line-height: 1.57;
  text-transform: uppercase;
}

.ds-2026 .section--dark .eyebrow {
  color: var(--nw-neutral-400);
}

.ds-2026 .item-index {
  color: var(--nw-red-text);
  font-size: 0.875rem;
}

/* Titoli/Sezione — Aktiv Grotesk Ex Regular 48/1.1. */
.ds-2026 .section-heading h2,
.ds-2026 .editorial-grid h2,
.ds-2026 .form-intro h2 {
  font-size: clamp(2rem, 8cqi, 3rem);
  line-height: 1.1;
}

/* Titoli/Display — Aktiv Grotesk Ex Bold 80/1. The tension statement is the
   page's one display line; its size stays bound to its grid track. */
.ds-2026 .tension-statement {
  font-weight: 700;
  line-height: 1;
}

/* Intro text — Mulish, one step up from body. Owner review 2026-10-18: the
   extended display face reads well on short titles and jars on running
   sentences, so on the landings it is kept to headings and short phrases. */
.ds-2026 .hero-lead,
.ds-2026 .section-heading p {
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
}

@media (min-width: 768px) {
  .ds-2026 .hero-lead,
  .ds-2026 .section-heading p {
    font-size: 1.1875rem;
  }
}

.ds-2026 .journey-item h3,
.ds-2026 .outcome-item h3,
.ds-2026 .method-item h3 {
  line-height: 1.15;
}

.ds-2026 .journey-item p,
.ds-2026 .outcome-item p,
.ds-2026 .method-item p,
.ds-2026 .faq-item p {
  font-size: 1rem;
  line-height: 1.75;
}

.ds-2026 .faq-item summary {
  font-weight: 400;
}

.ds-2026 .faq-item summary::after {
  color: var(--nw-primary);
}

/* ---- Buttons ---------------------------------------------------------------
   UI/Bottone — Aktiv Grotesk Ex Medium, upright, lowercase, pill. The July
   system set them in italic; the 2026 board does not. */
.ds-2026 .button-cta,
.ds-2026 .link-cta {
  min-height: 48px;
  padding: 12px 28px;
  font-family: var(--font-display);
  font-size: 1rem; /* Bottone M */
  font-style: normal;
  font-weight: 500;
  line-height: 1;
}

.ds-2026 .button-cta:hover,
.ds-2026 .link-cta:hover {
  background: var(--nw-accent-hover);
}

.ds-2026 .button-cta:active,
.ds-2026 .link-cta:active {
  background: var(--nw-accent-pressed);
}

/* button/focus-ring is ink, not red: a red ring vanishes on a red pill. */
.ds-2026 .button-cta:focus-visible,
.ds-2026 .link-cta:focus-visible {
  outline: 2px solid var(--nw-schwarz);
  outline-offset: 3px;
}

.ds-2026 .site-nav .button-cta {
  min-height: 44px;
  padding: 10px 22px;
  font-size: 0.875rem; /* Bottone S */
}

.ds-2026 .hero .button-cta,
.ds-2026 .link-cta--lg {
  min-height: 52px;
  padding: 14px 32px;
  font-size: 1.125rem; /* Bottone L */
}

/* ---- Signage hero ------------------------------------------------------------
   Service pages carry no photograph. The hero's visual is one of the four
   motifs of the nwdesigns visual signage, all built from the red stroke of the
   W: the solid shard (scheggia), the burst of fragments (raggiera), the rosette
   of rotated shards (spirale) and the echo of parallel outlines (eco). It is
   decorative — the SVG is inline, aria-hidden and never the LCP candidate, so
   the headline is. As on the main site's /servizi hero, it bleeds off the
   right edge rather than sitting framed in a column. */
.ds-2026 :is(.hero--signage, .hero--photo) {
  position: relative;
  align-items: center;
  overflow: clip;
  min-height: min(100svh, 760px);
  padding-block: 120px 64px;
}

.ds-2026 :is(.hero--signage, .hero--photo) .hero-grid {
  gap: 40px;
}

.ds-2026 :is(.hero--signage, .hero--photo) .hero-copy {
  position: relative;
  z-index: 1;
}

/* Titoli/Hero — Aktiv Grotesk Ex Regular 72/0.98, uppercase. */
.ds-2026 :is(.hero--signage, .hero--photo) h1 {
  margin-bottom: 28px;
  font-size: clamp(2.375rem, 9cqi, 4.5rem);
  line-height: 0.98;
}

/* Phone and tablet: as on the main site's mobile hero (owner, 2026-10-18), the
   mark opens the hero top right, bleeding off the edge, and the title follows
   below it. The header CTA stays in view, so the sign can lead. */
.ds-2026 .hero-signage {
  order: -1;
  justify-self: end;
  width: min(72vw, 340px);
  margin: 0 calc(-1 * min(20vw, 96px)) -8px 0;
  color: var(--nw-primary);
  pointer-events: none;
}

/* The shard is the one solid motif: at the size of the outlined ones it fills
   the screen, so on phone and tablet it stays a narrow accent. */
.ds-2026 .hero-signage[data-signage="scheggia"] {
  width: min(34vw, 180px);
  margin-right: 0;
}

/* The title breaks where it reads: "Stai pensando / di rifare / il logo?" on
   a phone, two lines on desktop. */
.ds-2026 :is(.hero--signage, .hero--photo) h1 .h1-line {
  display: block;
}

.ds-2026 .hero-signage svg {
  width: 100%;
  height: auto;
  overflow: visible;
}

/* The board draws these as hairlines (about 1px at 1:1); non-scaling stroke
   keeps them hairlines at any size. */
.ds-2026 .hero-signage [stroke] {
  stroke-width: 1;
}

@media (min-width: 768px) {
  .ds-2026 :is(.hero--signage, .hero--photo) {
    padding-block: 148px 88px;
  }
}

/* Tablet: the title lines are still stacked, so they are capped the same way. */
@media (min-width: 720px) and (max-width: 1023px) {
  .ds-2026 :is(.hero--signage, .hero--photo) h1 {
    font-size: min(4.5rem, calc((100vw - 80px) / var(--h1-em, 10.75)));
  }
}

/* Desktop: the mark takes the right track whole, sized so the hero stays
   inside the 760px fold instead of being stretched by its own decoration. */
@media (min-width: 1024px) {
  .ds-2026 :is(.hero--signage, .hero--photo) .hero-grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: clamp(32px, 4vw, 64px);
  }

  .ds-2026 .hero-signage {
    order: 0;
    justify-self: center;
    width: min(100%, clamp(380px, 36vw, 540px));
    margin: 0;
  }

  .ds-2026 :is(.hero--signage, .hero--photo) h1 .h1-line + .h1-line {
    display: inline;
  }

  /* No single title line may outgrow the copy column (.hero-copy is the
     inline-size container), or a long word wraps mid-word. */
  .ds-2026 :is(.hero--signage, .hero--photo) h1 {
    font-size: min(clamp(2.375rem, 9cqi, 4.5rem), calc(100cqi / var(--h1-em, 10.75)));
  }

  .ds-2026 .hero-signage[data-signage="scheggia"] {
    width: clamp(160px, 14vw, 210px);
  }
}

/* Motion: the rotating motifs turn once every two minutes, slow enough to read
   as material rather than as a loader. Off for reduced motion, where the
   static drawing is the whole experience. */
@keyframes nw-signage-turn {
  to {
    rotate: 360deg;
  }
}

@keyframes nw-signage-in {
  from {
    opacity: 0;
    scale: 0.94;
  }
}

@media (prefers-reduced-motion: no-preference) {
  .ds-2026 .hero-signage svg {
    animation: nw-signage-in 900ms var(--ease-house) both;
  }

  .ds-2026 .hero-signage[data-signage="spirale"] svg,
  .ds-2026 .hero-signage[data-signage="raggiera"] svg {
    animation:
      nw-signage-in 900ms var(--ease-house) both,
      nw-signage-turn 120s linear 900ms infinite;
  }
}

/* ---- Loop motif (Strategia) ------------------------------------------------
   Owner 2026-10-22, design system node "motivo loop": 180 outlines of the
   shard, one every 2 degrees, close into a ring; a small circle drifts inside
   it. The ring turns once a minute; the circle moves on the path traced from the
   owner's reference film (motivo_loop.mp4, one loop every 8 s). As in the
   owner's mock-up the ring is large and bleeds off the right edge; under
   reduced motion the circle rests where the film starts. */
.ds-2026 .hero-signage[data-signage="loop"] {
  position: relative;
  width: min(92vw, 440px);
  margin: -40px calc(-1 * min(34vw, 170px)) -16px 0;
}

/* Two layers: the ring turns as one composited image instead of repainting
   180 outlines a frame, and the circle drifts on its own layer above it. */
.ds-2026 .hero-signage[data-signage="loop"] .loop-ball-svg {
  position: absolute;
  inset: 0;
}

.ds-2026 .hero-signage[data-signage="loop"] .loop-ring {
  opacity: 0.7;
}

.ds-2026 .hero-signage circle.loop-ball {
  stroke-width: 2;
}

@media (min-width: 1024px) {
  .ds-2026 .hero-signage[data-signage="loop"] {
    position: absolute;
    top: 46%;
    right: calc(-1 * clamp(140px, 12vw, 260px));
    width: clamp(560px, 52vw, 980px);
    margin: 0;
    translate: 0 -50%;
  }
}

@keyframes nw-loop-ball {
  0% { translate: 0.0px 0.0px; }
  2.5% { translate: 7.6px 6.3px; }
  5% { translate: 26.7px 15.6px; }
  7.5% { translate: 49.2px 26.5px; }
  10% { translate: 72.6px 37.8px; }
  12.5% { translate: 97.3px 49.4px; }
  15% { translate: 120.8px 61.1px; }
  17.5% { translate: 144.8px 71.9px; }
  20% { translate: 167.0px 83.2px; }
  22.5% { translate: 186.6px 92.7px; }
  25% { translate: 196.7px 97.0px; }
  27.5% { translate: 193.3px 87.4px; }
  30% { translate: 181.3px 70.8px; }
  32.5% { translate: 168.9px 50.9px; }
  35% { translate: 155.4px 31.3px; }
  37.5% { translate: 142.4px 9.8px; }
  40% { translate: 128.6px -11.3px; }
  42.5% { translate: 114.2px -31.7px; }
  45% { translate: 101.7px -51.0px; }
  47.5% { translate: 91.3px -68.1px; }
  50% { translate: 82.9px -73.4px; }
  52.5% { translate: 80.8px -65.3px; }
  55% { translate: 77.5px -44.8px; }
  57.5% { translate: 75.3px -20.7px; }
  60% { translate: 72.3px 4.4px; }
  62.5% { translate: 69.0px 29.7px; }
  65% { translate: 66.7px 55.3px; }
  67.5% { translate: 63.7px 80.4px; }
  70% { translate: 59.7px 104.0px; }
  72.5% { translate: 57.3px 124.5px; }
  75% { translate: 58.4px 134.5px; }
  77.5% { translate: 51.7px 130.4px; }
  80% { translate: 45.9px 116.3px; }
  82.5% { translate: 39.1px 101.3px; }
  85% { translate: 31.7px 85.5px; }
  87.5% { translate: 24.2px 69.2px; }
  90% { translate: 17.3px 53.0px; }
  92.5% { translate: 9.7px 37.1px; }
  95% { translate: 3.0px 21.9px; }
  97.5% { translate: -1.7px 8.9px; }
  100% { translate: 0px 0px; }
}

/* Owner 2026-10-22: the outer ring turns slowly and without pause, one turn a
   minute, while the circle keeps its own path. */
@media (prefers-reduced-motion: no-preference) {
  .ds-2026 .hero-signage circle.loop-ball {
    animation: nw-loop-ball 8s linear infinite;
  }

  .ds-2026 .hero-signage[data-signage="loop"] .loop-ring-svg {
    animation:
      nw-signage-in 900ms var(--ease-house) both,
      nw-signage-turn 60s linear 900ms infinite;
    will-change: rotate;
  }
}

/* ---- Logo on dark ground --------------------------------------------------
   main.css whitens the footer logo with a filter, red stroke included. The
   2026 pages link the light variant instead (red #E21518, ink #F2F2F2, as on
   the main site's footer), so the filter has to step aside. */
.ds-2026 .site-footer .brand-mark img {
  filter: none;
}

/* ---- Studio section: "Lavoriamo da Roma" ---------------------------------
   The team film from the main site's Studio page, so a paid visitor sees the
   people and the room before writing to them. Played by main.js like every
   managed video: never autoplay, only in view, poster under reduced motion. */
.ds-2026 .studio-grid {
  display: grid;
  gap: 40px;
  align-items: center;
}

.ds-2026 .studio-media {
  max-width: none;
  margin: 0;
}

.ds-2026 .studio-media video {
  aspect-ratio: 16 / 9;
}

.ds-2026 .studio-copy {
  max-width: 560px;
  min-width: 0;
  container-type: inline-size;
}

.ds-2026 .studio-copy h2 {
  margin-bottom: 24px;
  font-size: clamp(2rem, 8cqi, 3rem);
  line-height: 1.1;
}

.ds-2026 .studio-copy p {
  color: var(--nw-foreground-secondary);
}

@media (min-width: 1024px) {
  .ds-2026 .studio-grid {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: clamp(40px, 5vw, 80px);
  }
}

/* ---- Portfolio carousel: "Come lavoriamo" --------------------------------
   Up to six projects from nwdesigns.it/portfolio, each on its own 3x4 cover
   (the portfolio grid's format) and linked to its case study. The track is a
   native scroll-snap list: it scrolls by swipe, trackpad and keyboard with no
   JavaScript, and main.js only adds the prev/next buttons. A phone shows one
   card and a sliver of the next, so the swipe is discoverable; desktop shows
   three. */
.ds-2026 .work-carousel {
  position: relative;
}

.ds-2026 .work-track {
  display: grid;
  grid-auto-columns: 78%;
  grid-auto-flow: column;
  gap: 20px;
  margin: 0;
  padding: 0 0 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
}

.ds-2026 .work-track::-webkit-scrollbar {
  display: none;
}

.ds-2026 .work-track:focus-visible {
  outline: 2px solid var(--nw-schwarz);
  outline-offset: 6px;
}

/* Positioned so the visually hidden "(si apre in una nuova scheda)" inside each
   card stays inside the scrolling track; unanchored, the last card's copy sat
   at x=1579 on a phone and widened the whole page. */
.ds-2026 .work-item {
  position: relative;
  min-width: 0;
  scroll-snap-align: start;
}

.ds-2026 .carousel-controls {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  margin-top: 28px;
}

.ds-2026 .carousel-controls[hidden],
.ds-2026 .work-carousel.is-static .carousel-controls {
  display: none;
}

/* Bottone icona from the 2026 board: an outlined circle, ink on light. */
.ds-2026 .carousel-button {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--nw-schwarz);
  border-radius: 50%;
  background: transparent;
  color: var(--nw-schwarz);
  cursor: pointer;
  transition-property: background-color, color, opacity;
  transition-duration: 150ms;
  transition-timing-function: var(--ease-standard);
}

.ds-2026 .carousel-button--prev svg {
  rotate: 180deg;
}

.ds-2026 .carousel-button:hover:not(:disabled) {
  background: var(--nw-schwarz);
  color: var(--nw-white);
}

.ds-2026 .carousel-button:focus-visible {
  outline: 2px solid var(--nw-schwarz);
  outline-offset: 3px;
}

.ds-2026 .carousel-button:disabled {
  opacity: 0.3;
  cursor: default;
}

@media (min-width: 768px) {
  .ds-2026 .work-track {
    grid-auto-columns: calc((100% - 32px) / 2.2);
    gap: 32px;
  }
}

@media (min-width: 1024px) {
  .ds-2026 .work-track {
    grid-auto-columns: calc((100% - 64px) / 3);
  }
}

/* Campaign "Altri lavori" (owner 2026-10-19): after the sector cases, the
   portfolio is a supporting row — smaller cards, all six in one row on
   desktop, two and a bit on a phone. */
.ds-2026 .work-carousel--compact .work-track {
  grid-auto-columns: 46%;
  gap: 14px;
}

@media (min-width: 768px) {
  .ds-2026 .work-carousel--compact .work-track {
    grid-auto-columns: calc((100% - 3 * 20px) / 3.4);
    gap: 20px;
  }
}

@media (min-width: 1024px) {
  .ds-2026 .work-carousel--compact .work-track {
    grid-auto-columns: calc((100% - 5 * 20px) / 6);
  }
}

.ds-2026 .work-carousel--compact .work-link img {
  margin-bottom: 10px;
}

.ds-2026 .work-carousel--compact .work-name {
  font-size: 0.9375rem;
}

.ds-2026 .work-carousel--compact .work-scope {
  font-size: 0.8125rem;
  line-height: 1.5;
}

.ds-2026 .work-carousel--compact .work-more {
  font-size: 0.75rem;
}

.ds-2026 .work-link {
  display: grid;
  gap: 6px;
  color: inherit;
  text-decoration: none;
}

.ds-2026 .work-link img {
  width: 100%;
  height: auto;
  margin-bottom: 14px;
  outline: 1px solid rgba(0, 0, 0, 0.08);
  outline-offset: -1px;
  transition: opacity 300ms var(--ease-house);
}

.ds-2026 .work-name {
  color: var(--nw-schwarz);
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.2;
}

.ds-2026 .work-scope {
  color: var(--nw-foreground-secondary);
  font-size: 0.9375rem;
}

.ds-2026 .work-more {
  justify-self: start;
  margin-top: 6px;
  border-bottom: 1px solid var(--nw-primary);
  color: var(--nw-schwarz);
  font-family: var(--font-display);
  font-size: 0.875rem;
  font-weight: 500;
}

.ds-2026 .work-link:hover img,
.ds-2026 .work-link:focus-visible img {
  opacity: 0.88;
}

.ds-2026 .work-link:hover .work-more,
.ds-2026 .work-link:focus-visible .work-more {
  color: var(--nw-accent-hover);
}

.ds-2026 .visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Perché scegliere nwdesigns ------------------------------------------
   Owner review 2026-10-18: the freelance / marketing-agency table did not
   work on a phone and read defensive. In its place, five numbered reasons;
   each keeps one short line on what the alternative does differently, set
   apart in secondary ink, and a closing note says when a freelance is the
   right call. Same editorial rhythm as the process list: a hairline per
   item, no boxes. */
.ds-2026 .reason-list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid var(--nw-border);
}

.ds-2026 .reason {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  gap: 6px 16px;
  padding-block: 24px;
  border-top: 1px solid var(--nw-border);
}

.ds-2026 .reason .item-index {
  grid-row: 1 / span 2;
  margin: 0;
  padding-top: 4px;
  color: var(--nw-red-text);
  font-size: 0.875rem;
}

.ds-2026 .reason h3 {
  margin: 0;
  color: var(--nw-schwarz);
  font-size: 1.25rem;
  font-weight: 400;
  line-height: 1.25;
}

.ds-2026 .reason-body p {
  margin: 0;
  color: var(--nw-schwarz);
}

.ds-2026 .reason-body .reason-contrast {
  margin-top: 8px;
  color: var(--nw-foreground-secondary);
  font-size: 0.9375rem;
}

.ds-2026 .reason-note {
  max-width: 62ch;
  margin: 32px 0 0;
  color: var(--nw-foreground-secondary);
}

@media (min-width: 900px) {
  .ds-2026 .reason {
    grid-template-columns: 64px minmax(0, 4fr) minmax(0, 7fr);
    gap: 0 32px;
    padding-block: 32px;
  }

  .ds-2026 .reason .item-index {
    grid-row: auto;
  }

  .ds-2026 .reason h3 {
    font-size: 1.5rem;
  }
}

/* ---- Studio figures ------------------------------------------------------ */
.ds-2026 .studio-copy .figures {
  margin: 8px 0 24px;
}

/* ---- Client logo strip ----------------------------------------------------
   The client marks of the main site's /servizi grid (frontend/src/data/
   client-logos.ts), minus Ambrosiano, which the owner never cites. Two
   identical tracks drift left as one loop; the second is aria-hidden with
   empty alts, so a screen reader hears each client once. Marks are unified
   to ink so 31 brand palettes do not compete with the covers below. */
/* Its own band straight under the hero (owner, 2026-10-18): the first thing
   below the fold, and at 1440x900 its top edge already shows inside it. */
.ds-2026 .client-band {
  padding-block: 40px;
  border-top: 1px solid var(--nw-border);
}

/* Owner 2026-10-22: no visible "Tra i nostri clienti" over the logos. The
   heading stays for screen readers, where it names the band and the strip. */
.ds-2026 .client-strip-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Full-bleed: the marks run edge to edge of the window rather than being cut
   at the text column, where a half logo ("OBET") read as a clipping bug. The
   label above stays on the column. body has overflow-x: clip in main.css. */
.ds-2026 .logo-marquee {
  display: flex;
  overflow: hidden;
  margin-inline: calc(50% - 50vw);
}

/* Owner 2026-10-22: a calmer, more even row. Each mark is sized to about the
   same visual area (wide wordmarks wider, compact marks taller, within 170 x
   52 px) instead of one fixed width, about 15% larger than before, with more
   air between them; the drift slows so the longer row keeps its pace. */
.ds-2026 .logo-track {
  display: flex;
  flex: none;
  gap: 64px;
  align-items: center;
  margin: 0;
  padding: 0 64px 0 0;
  list-style: none;
  animation: nw-logo-drift 100s linear infinite;
}

@media (min-width: 768px) {
  .ds-2026 .logo-track {
    gap: 96px;
    padding-right: 96px;
  }
}

/* WCAG 2.2.2: anything that moves on its own for more than five seconds needs
   a way to stop it. Owner, 2026-10-18: no pause button. The strip itself is
   focusable instead, so it stops under the pointer, when tapped on a phone
   (the tap focuses it) and when reached by keyboard; under reduced motion it
   never moves at all. */
.ds-2026 .logo-marquee:hover .logo-track,
.ds-2026 .logo-marquee:focus-within .logo-track {
  animation-play-state: paused;
}

.ds-2026 .logo-marquee:focus-visible {
  outline: 2px solid var(--nw-schwarz);
  outline-offset: 4px;
}

.ds-2026 .logo-track img {
  display: block;
  max-width: none;
  height: auto;
  filter: grayscale(1);
  opacity: 0.9;
}

@keyframes nw-logo-drift {
  to {
    translate: -100% 0;
  }
}

/* Under reduced motion nothing drifts: the row stands still and scrolls by
   hand. Not a wrapped grid — straight under the hero, 31 marks in rows made
   the band 1,156 px tall on a phone. */
@media (prefers-reduced-motion: reduce) {
  .ds-2026 .logo-marquee {
    overflow-x: auto;
    scrollbar-width: none;
  }

  .ds-2026 .logo-marquee::-webkit-scrollbar {
    display: none;
  }

  /* Still, the row starts on the text column (the .shell edge) instead of
     flush against the window. */
  .ds-2026 .logo-track {
    padding-inline: max(20px, calc(50vw - 590px));
    animation: none;
  }

  .ds-2026 .logo-track[aria-hidden="true"] {
    display: none;
  }
}

/* ---- Figures, wrap-safe ----------------------------------------------------
   main.css draws the separator dot as an absolutely positioned ::before at
   -13px, so when a narrow column wraps the row, the dot of the first item on
   the new line hangs outside the text edge (owner screenshot, 2026-10-18).
   Here the dot is an inline ::after on every item but the last: it stays
   glued to the label before it, the line can only break after it, and a
   wrapped line therefore starts flush with a label, never with a dot. */
.ds-2026 .figures {
  display: block;
}

.ds-2026 .figures span {
  display: inline;
  white-space: nowrap;
}

.ds-2026 .figures span + span::before {
  content: none;
}

.ds-2026 .figures span:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 4px;
  height: 4px;
  margin: 0 12px 0.2em 10px;
  background: var(--nw-primary);
  vertical-align: middle;
}

/* ---- Carousel paging and pause --------------------------------------------
   Desktop pages three at a time (main.js), so it snaps only on every third
   card there: a hand scroll settles on the same boundaries the buttons and
   the timer use. Narrower screens keep a snap point per card. */
@media (min-width: 1024px) {
  .ds-2026 .work-item {
    scroll-snap-align: none;
  }

  .ds-2026 .work-item:nth-child(3n + 1) {
    scroll-snap-align: start;
  }
}

.ds-2026 .carousel-toggle {
  margin-right: auto;
}

.ds-2026 .carousel-toggle[hidden] {
  display: none;
}

.ds-2026 .carousel-toggle .icon-play,
.ds-2026 .carousel-toggle.is-paused .icon-pause {
  display: none;
}

.ds-2026 .carousel-toggle.is-paused .icon-play {
  display: block;
}

/* ---- FAQ in two groups ----------------------------------------------------
   Owner review 2026-10-18: questions about how nwdesigns works (price range
   included) first, then the questions people actually type into Google about
   logos. Each group is titled so a reader — and an answer engine — can tell
   the studio's own terms from general guidance. */
.ds-2026 .faq-group + .faq-group {
  margin-top: clamp(48px, 6vw, 72px);
}

.ds-2026 .faq-group-title {
  margin-bottom: 16px;
  color: var(--nw-foreground-secondary);
  font-family: var(--font-label);
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.57;
  text-transform: uppercase;
}

/* ---- One ground ------------------------------------------------------------
   Owner review 2026-10-18: no alternating grey and Egg Shell bands — the jump
   between the two read as a seam. Every section sits on Egg Shell, and a
   hairline marks where one ends and the next begins. */
.ds-2026 .section--neutral {
  background: var(--nw-eggshell);
}

.ds-2026 main > section + section {
  border-top: 1px solid var(--nw-border);
}

/* ---- Emphasis, breadcrumb, related services ------------------------------- */
.ds-2026 strong {
  color: var(--nw-schwarz);
  font-weight: 650;
}

.ds-2026 .breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 0;
  margin: 0 0 18px;
  padding: 0;
  color: var(--nw-foreground-secondary);
  font-size: 0.8125rem;
  list-style: none;
}

.ds-2026 .breadcrumb li + li::before {
  content: "›";
  margin-inline: 8px;
  color: var(--nw-border-strong);
}

.ds-2026 .breadcrumb a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}

.ds-2026 .breadcrumb a:hover,
.ds-2026 .breadcrumb a:focus-visible {
  border-bottom-color: currentColor;
}

.ds-2026 .breadcrumb [aria-current="page"] {
  color: var(--nw-schwarz);
}

.ds-2026 .related-note {
  max-width: 720px;
  margin: 40px 0 0;
  color: var(--nw-foreground-secondary);
}

.ds-2026 .related-note a {
  color: var(--nw-schwarz);
  text-decoration-color: var(--nw-primary);
  text-underline-offset: 3px;
}

/* ---- Google reviews --------------------------------------------------------
   Owner, 2026-10-18: a static selection of the studio's Google reviews, each
   with "Leggi di più su Google". Every card is a registry row (REV-2026-*).
   The text is the reviewer's, verbatim; Google's own cuts end in "…". Long
   text is clamped on screen only — the full wording stays in the markup.
   Sharp and editorial like the rest: a rule above each review, no card box.
   One scrollable row at every width (owner, 2026-10-18), on the portfolio's
   carousel: three across on desktop, swipe on a phone, arrows from main.js.
   No pause button means no timer — it only moves when the visitor moves it. */
.ds-2026 .review-list {
  display: grid;
  grid-auto-columns: 84%;
  grid-auto-flow: column;
  gap: 20px;
  margin: 0;
  padding: 0 0 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
}

.ds-2026 .review-list::-webkit-scrollbar {
  display: none;
}

@media (min-width: 768px) {
  .ds-2026 .review-list {
    grid-auto-columns: calc((100% - 32px) / 2.2);
    gap: 32px;
  }
}

@media (min-width: 1024px) {
  .ds-2026 .review-list {
    grid-auto-columns: calc((100% - 64px) / 3);
  }
}

.ds-2026 .review-carousel.is-static .carousel-controls {
  display: none;
}

.ds-2026 .testimonial {
  scroll-snap-align: start;
  position: relative; /* anchors the hidden "(si apre in una nuova scheda)" inside the row */
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-top: 24px;
  border-top: 1px solid var(--nw-schwarz);
}

.ds-2026 .testimonial figure {
  margin: 0;
}

.ds-2026 .review-stars {
  margin: 0 0 14px;
  color: var(--nw-red-text);
  font-size: 0.875rem;
  letter-spacing: 0.18em;
  line-height: 1;
}

.ds-2026 .testimonial blockquote {
  margin: 0;
}

.ds-2026 .testimonial blockquote p {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  color: var(--nw-schwarz);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  line-clamp: 6;
}

.ds-2026 .testimonial figcaption {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 18px;
}

.ds-2026 .review-name {
  color: var(--nw-schwarz);
  font-family: var(--font-display);
  font-weight: 500;
}

.ds-2026 .review-source {
  color: var(--nw-foreground-secondary);
  font-family: var(--font-label);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.ds-2026 .review-more {
  margin-top: auto;
  align-self: flex-start;
  font-size: 0.9375rem;
}

.ds-2026 .review-note {
  margin: 40px 0 0;
  color: var(--nw-foreground-secondary);
  font-size: 0.9375rem;
}

/* ---- Phone reading ---------------------------------------------------------
   Owner, 2026-10-18: on a phone the quote button sits top right in the fixed
   header, and running text is a step smaller with wider side margins. With
   the CTA always in the header, the floating bottom button would only repeat
   it, so 2026 pages drop it (and the body padding it reserved). */
.ds-2026 .floating-cta {
  display: none;
}

.ds-2026.floating-cta-enabled {
  padding-bottom: 0;
}

@media (max-width: 719px) {
  .ds-2026 .shell {
    width: min(100% - 48px, 1180px);
  }

  .ds-2026 .site-nav {
    gap: 12px;
  }

  .ds-2026 .brand-mark img {
    width: 128px;
  }

  .ds-2026 .site-nav .button-cta {
    display: inline-flex;
    min-height: 44px;
    padding: 8px 16px;
    font-size: 0.8125rem;
    white-space: nowrap;
  }

  .ds-2026 {
    font-size: 0.9375rem; /* 15px body */
    line-height: 1.7;
  }

  .ds-2026 .hero-lead,
  .ds-2026 .section-heading p {
    font-size: 1rem;
    line-height: 1.65;
  }

  .ds-2026 :is(.hero--signage, .hero--photo) {
    padding-top: 96px;
  }

  .ds-2026 :is(.hero--signage, .hero--photo) .hero-grid {
    gap: 24px;
  }

  /* Sized from the page's longest title line (--h1-em, set by the
     generator): every line holds on one row at any phone width. */
  .ds-2026 :is(.hero--signage, .hero--photo) h1 {
    font-size: clamp(1.5rem, calc((100vw - 48px) / var(--h1-em, 10.75)), 2.25rem);
  }

  .ds-2026 .section-heading h2,
  .ds-2026 .editorial-grid h2,
  .ds-2026 .form-intro h2 {
    font-size: 1.75rem;
  }

  .ds-2026 .testimonial blockquote p {
    font-size: 0.9375rem;
  }
}

@media (max-width: 719px) and (prefers-reduced-motion: reduce) {
  .ds-2026 .logo-track {
    padding-inline: 24px;
  }
}

/* ---- Photo hero (sector campaigns) -----------------------------------------
   Owner, 2026-10-18: the campaign pages take the 2026 design but keep their
   editorial photograph. It sits where the signage sits — top on a phone,
   right track on desktop — and stays the LCP candidate it always was. */
.ds-2026 .hero--photo .hero-media {
  order: -1;
}

.ds-2026 .hero--photo .hero-media figcaption {
  font-family: var(--font-label);
  color: var(--nw-foreground-secondary);
}

@media (min-width: 1024px) {
  .ds-2026 .hero--photo .hero-media {
    order: 0;
    align-self: center;
  }
}

/* Sector clients: the proof list from main.css, on the 2026 ground. */
.ds-2026 .sector-section .proof-list {
  margin-top: 8px;
}

/* ---- Sector cases ----------------------------------------------------------
   Owner design 2026-10-18: one block per client chosen from the portfolio —
   a short text that names the client, a lead image, then three project
   images. Phone: text, image, and the three images as a swipeable row.
   Desktop: text beside a wide lead image, sides alternating, the three images
   as a row underneath. Sharp edges, as every editorial surface. */
.ds-2026 .sector-cases {
  display: grid;
  gap: 64px;
  margin-top: 8px;
}

.ds-2026 .sector-cases + .proof-list {
  margin-top: 64px;
}

.ds-2026 .sector-case {
  display: grid;
  gap: 20px;
  min-width: 0;
}

.ds-2026 .sector-case-body {
  position: relative;
  min-width: 0;
}

.ds-2026 .sector-case-meta {
  margin: 0 0 10px;
  color: var(--nw-red-text);
  font-family: var(--font-label);
  font-size: 0.875rem;
  line-height: 1.57;
  text-transform: uppercase;
}

.ds-2026 .sector-case h3 {
  margin: 0 0 14px;
  color: var(--nw-schwarz);
  font-size: clamp(1.375rem, 5.5cqi, 2rem);
  font-weight: 400;
  line-height: 1.15;
}

.ds-2026 .sector-case-body p:not(.sector-case-meta) {
  margin: 0 0 16px;
  color: var(--nw-foreground-secondary);
}

.ds-2026 .sector-case-body strong {
  color: var(--nw-schwarz);
}

.ds-2026 .sector-case-lead {
  margin: 0;
}

.ds-2026 .sector-case img {
  display: block;
  width: 100%;
  height: auto;
  outline: 1px solid rgba(0, 0, 0, 0.08);
  outline-offset: -1px;
}

.ds-2026 .sector-case-work {
  display: grid;
  grid-auto-columns: 62%;
  grid-auto-flow: column;
  gap: 12px;
  margin: 0;
  padding: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
}

.ds-2026 .sector-case-work::-webkit-scrollbar {
  display: none;
}

.ds-2026 .sector-case-work li {
  min-width: 0;
  scroll-snap-align: start;
}

/* Text-only cases: same text, the logo when there is one, no images. They
   sit in columns under the full cases, divided by a hairline like the reason
   list. */
.ds-2026 .sector-notes {
  display: grid;
  gap: 40px;
  margin-top: 8px;
}

.ds-2026 .sector-cases + .sector-notes {
  margin-top: 72px;
}

.ds-2026 .sector-note {
  position: relative;
  min-width: 0;
  padding-top: 24px;
  border-top: 1px solid var(--nw-border);
}

.ds-2026 .sector-note-mark {
  display: block;
  width: auto;
  max-width: 160px;
  height: 48px;
  margin-bottom: 20px;
  object-fit: contain;
  object-position: left center;
}

.ds-2026 .sector-note h3 {
  margin: 0 0 12px;
  color: var(--nw-schwarz);
  font-size: 1.375rem;
  font-weight: 400;
  line-height: 1.2;
}

.ds-2026 .sector-note p:not(.sector-case-meta) {
  margin: 0 0 16px;
  color: var(--nw-foreground-secondary);
}

.ds-2026 .sector-note strong {
  color: var(--nw-schwarz);
}

@media (min-width: 720px) {
  .ds-2026 .sector-notes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 40px;
  }
}

@media (min-width: 1024px) {
  .ds-2026 .sector-notes:has(> :nth-child(3)) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 720px) {
  .ds-2026 .sector-case-work {
    grid-auto-columns: auto;
    grid-auto-flow: row;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    overflow: visible;
  }
}

@media (min-width: 1024px) {
  .ds-2026 .sector-cases {
    gap: 112px;
  }

  .ds-2026 .sector-case {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    column-gap: 64px;
    row-gap: 20px;
    align-items: center;
  }

  .ds-2026 .sector-case-work {
    grid-column: 1 / -1;
    order: 2;
  }

  .ds-2026 .sector-case:nth-child(even) {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }

  .ds-2026 .sector-case:nth-child(even) .sector-case-body {
    order: 1;
  }
}

/* A campaign CTA can run to six words; in the phone header it gives way to a
   short form so the wordmark keeps its size. The long label stays the link's
   accessible name (the short one is aria-hidden). */
.ds-2026 .site-nav .cta-short {
  display: none;
}

@media (max-width: 719px) {
  .ds-2026 .site-nav .cta-long {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .ds-2026 .site-nav .cta-short {
    display: inline;
  }
}
