/* ============================================================
   DAVIDE SEGA — sections
   ============================================================ */

/* ============================================================ NAV */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: var(--z-nav);
  padding: 1.1rem var(--gutter);
  /* Bound to the token rather than inherited: when a light project
     panel is on screen the nav takes data-surface="light", and only
     an explicit binding lets the ink follow the flipped token. */
  color: var(--fg);
  transition: padding var(--d-mid) var(--e-glide),
              color var(--d-slow) var(--e-glide);
}
.nav__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  padding: 0.5rem 0.5rem 0.5rem 0.9rem;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  transition: background-color var(--d-mid) var(--e-glide),
              border-color var(--d-mid) var(--e-glide),
              backdrop-filter var(--d-mid) var(--e-glide);
}
/* Glass only once detached from the top — a blurred bar over the hero
   at rest is pure GPU cost for no legibility gain. */
.nav.is-stuck .nav__inner {
  background: color-mix(in oklab, var(--bg) 72%, transparent);
  border-color: var(--hair);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
}
.nav.is-stuck { padding-top: 0.7rem; padding-bottom: 0.7rem; }

.nav__brand { display: flex; align-items: center; gap: 0.75rem; margin-right: auto; min-width: 0; }
/* No radius: the mark is transparent artwork, not a tile — there is no
   box to round. The monogram is the shell's own bone so it reads on the
   dark bar; the arrow keeps the brand orange, the one piece of colour
   on the page that belongs to Davide rather than to a project. */
.nav__brand img { width: 26px; height: 26px; flex: 0 0 auto; }
.nav__brand-name {
  font-size: 0.95rem; font-weight: 600; letter-spacing: -0.02em;
  line-height: 1; white-space: nowrap;
}
/* On a phone the role line wraps to two lines and drags the whole bar
   to 75px tall. The wordmark alone carries the identity at that size. */
.nav__brand-role { display: none; }
@media (min-width: 620px) {
  .nav__brand-role {
    display: block;
    font-family: var(--f-mono);
    font-size: 0.5625rem; letter-spacing: 0.16em; text-transform: uppercase;
    white-space: nowrap;
    color: var(--fg-3); margin-top: 4px;
  }
}

.nav__links { display: none; align-items: center; gap: 0.35rem; }
@media (min-width: 1000px) { .nav__links { display: flex; } }

.nav__link {
  position: relative;
  padding: 0.5rem 0.9rem;
  border-radius: var(--r-pill);
  font-size: var(--t-small);
  color: var(--fg-2);
  transition: color var(--d-hover) ease,
              background-color var(--d-hover) ease,
              transform var(--d-press) var(--e-out);
}
.nav__link:hover { color: var(--fg); background: var(--accent-soft); }
.nav__link[aria-current="true"] { color: var(--fg); }
.nav__link[aria-current="true"]::after {
  content: "";
  position: absolute; left: 50%; bottom: 0.15rem;
  width: 3px; height: 3px; margin-left: -1.5px;
  border-radius: 50%; background: var(--accent);
}

/* IT / EN — a sliding thumb, not two buttons that light up. */
.lang {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  padding: 3px;
  border: 1px solid var(--hair);
  border-radius: var(--r-pill);
}
.lang__thumb {
  position: absolute;
  top: 3px; left: 3px;
  width: calc(50% - 3px); height: calc(100% - 6px);
  border-radius: var(--r-pill);
  background: var(--accent);
  transition: transform var(--d-mid) var(--e-glide);
}
.lang[data-lang="en"] .lang__thumb { transform: translateX(100%); }
.lang button {
  position: relative;
  padding: 0.32rem 0.7rem;
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  font-weight: 500; letter-spacing: 0.1em;
  color: var(--fg-3);
  transition: color var(--d-mid) var(--e-glide),
              transform var(--d-press) var(--e-out);
}
.lang button[aria-pressed="true"] { color: var(--accent-ink); }

.nav__cta { display: none; }
@media (min-width: 700px) { .nav__cta { display: inline-flex; } }

/* Hamburger — the bars rotate into an X, they don't swap icons. */
.burger {
  display: grid; place-items: center;
  /* flex-basis pinned: without it the flex row squashes the circle
     into an ellipse on a narrow phone. */
  flex: 0 0 auto;
  width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--hair); border-radius: 50%;
}
@media (min-width: 1000px) { .burger { display: none; } }
.burger span {
  display: block; width: 15px; height: 1.5px;
  background: var(--fg); border-radius: 2px;
  transition: transform var(--d-mid) var(--e-spring), opacity 160ms linear;
}
.burger span:first-child { transform: translateY(-3.5px); }
.burger span:last-child  { transform: translateY(3.5px); }
.burger[aria-expanded="true"] span:first-child { transform: translateY(0.75px) rotate(45deg); }
.burger[aria-expanded="true"] span:last-child  { transform: translateY(-0.75px) rotate(-45deg); }

/* Full-screen menu. Same rule as the overlays: `display: grid` beats
   the UA style for [hidden], so the attribute is honoured here. */
.menu[hidden] { display: none; }

.menu {
  position: fixed; inset: 0;
  z-index: calc(var(--z-nav) - 1);
  display: grid;
  align-content: center;
  padding: calc(var(--nav-h) + 3rem) var(--gutter) var(--sp-8);
  background: color-mix(in oklab, var(--bg) 86%, transparent);
  backdrop-filter: blur(28px) saturate(140%);
  -webkit-backdrop-filter: blur(28px) saturate(140%);
  opacity: 0;
  transition: opacity var(--d-mid) var(--e-glide);
}
.menu.is-open { opacity: 1; }
.menu a {
  display: flex; align-items: baseline; gap: 1.1rem;
  padding-block: clamp(0.6rem, 2vw, 1.1rem);
  border-bottom: 1px solid var(--hair);
  font-size: clamp(2rem, 9vw, 3.4rem);
  font-weight: 500; letter-spacing: -0.04em; line-height: 1;
  opacity: 0; transform: translateY(2.5rem);
  transition: opacity var(--d-mid) var(--e-out), transform var(--d-slow) var(--e-out);
  transition-delay: calc(var(--i) * 65ms);
}
.menu.is-open a { opacity: 1; transform: none; }
.menu a .num { font-size: var(--t-micro); }

/* ==================================================== SECTION RAIL */

.rail {
  position: fixed;
  left: max(1.1rem, calc((100vw - var(--maxw)) / 2 - 3.2rem));
  top: 50%; transform: translateY(-50%);
  z-index: var(--z-rail);
  display: none;
  flex-direction: column; gap: 1.05rem;
  color: var(--fg);
  transition: color var(--d-slow) var(--e-glide);
}
/* Only once the free gutter is wide enough to hold both the tick and
   its hover label without either touching the text column. Below
   this the top nav already covers navigation on its own. */
@media (min-width: 1560px) { .rail { display: flex; } }

.rail a {
  display: flex; align-items: center; gap: 0.7rem;
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.12em; color: var(--fg-4);
  transition: color var(--d-mid) var(--e-out);
}
.rail a::before {
  content: ""; width: 14px; height: 1px;
  background: currentColor;
  transition: width var(--d-mid) var(--e-glide), background-color var(--d-mid) var(--e-out);
}
.rail a:hover { color: var(--fg-2); }
.rail a[aria-current="true"] { color: var(--fg); }
.rail a[aria-current="true"]::before { width: 30px; background: var(--accent); }

/* The label is a hover affordance only. Showing it for the current
   section too would push a word of chrome into the headline column
   at exactly the widths where the rail appears. Position is the
   marker; the word is the confirmation. */
.rail__label {
  position: absolute; left: 2.4rem;
  white-space: nowrap;
  opacity: 0; transform: translateX(-4px);
  pointer-events: none;
  transition: opacity var(--d-mid) var(--e-out), transform var(--d-mid) var(--e-out);
}
.rail a { position: relative; }
.rail a:hover .rail__label { opacity: 1; transform: none; }

/* ========================================================== HERO */

.hero {
  position: relative;
  padding-top: calc(var(--nav-h) + clamp(3rem, 8vh, 7rem));
  padding-bottom: clamp(3rem, 5vw, 5.5rem);
  min-height: 100svh;
  display: flex; align-items: center;
}

/* A single soft pool of light behind the headline. Static, cheap,
   and it stops the near-black field from reading as a flat void. */
.hero::before {
  content: "";
  position: absolute;
  left: -10%; top: -20%;
  width: 85%; aspect-ratio: 1;
  background: radial-gradient(circle at 40% 40%, rgb(239 238 236 / 0.055), transparent 62%);
  pointer-events: none;
}

.hero__grid {
  display: grid;
  gap: clamp(3rem, 6vw, 5.5rem);
  width: 100%;
  align-items: center;
}
@media (min-width: 1000px) {
  .hero__grid { grid-template-columns: minmax(0, 1.32fr) minmax(0, 1fr); }
}

.hero h1 {
  font-size: var(--t-h1);
  letter-spacing: -0.048em;
  line-height: 0.93;
  margin-top: 1.5rem;
  margin-bottom: 1.9rem;
  max-width: 14ch;
}
.hero h1 .serif-em { letter-spacing: -0.03em; }

.hero__sub { max-width: 46ch; }

.hero__cta {
  display: flex; flex-wrap: wrap; gap: 0.75rem;
  margin-top: 2.4rem;
}

.hero__meta {
  display: grid;
  gap: 1px;
  margin-top: clamp(3rem, 6vw, 4.5rem);
  background: var(--hair);
  border-block: 1px solid var(--hair);
}
@media (min-width: 560px) { .hero__meta { grid-template-columns: 1fr 1fr; } }
.hero__meta > div { background: var(--bg); padding: 1.1rem 0; }
@media (min-width: 560px) { .hero__meta > div + div { padding-left: 1.5rem; } }
.hero__meta dt {
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3);
  margin-bottom: 0.5rem;
}
.hero__meta dd { font-size: var(--t-small); color: var(--fg); }

/* -------------------------------------------------- Vitals panel */

/* Replaces the old mock dashboard. Every number here is measured by
   the browser on this page at runtime — see js/vitals.js. */
.vitals { font-family: var(--f-mono); }
.vitals .plate__core { padding: 1.4rem 1.5rem 1.5rem; }

.vitals__bar {
  display: flex; align-items: center; gap: 0.65rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--hair);
  font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fg-3);
}
.vitals__dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  margin-left: auto;
  animation: pulse 2.4s var(--e-inout) infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.28; } }

.vitals__hero { padding-block: 1.5rem 1.35rem; }
.vitals__hero .k {
  font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fg-3);
}
.vitals__figure {
  display: flex; align-items: baseline; gap: 0.3rem;
  margin-top: 0.55rem;
  font-family: var(--f-display);
  font-size: clamp(2.6rem, 1.4rem + 3vw, 3.8rem);
  font-weight: 500; letter-spacing: -0.05em; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.vitals__figure .u {
  font-family: var(--f-mono); font-size: 0.9rem; font-weight: 400;
  letter-spacing: 0; color: var(--fg-3);
}
.vitals__note { font-size: var(--t-micro); color: var(--fg-3); margin-top: 0.7rem; line-height: 1.5; }

.vitals__rows { display: grid; gap: 1px; background: var(--hair); border-top: 1px solid var(--hair); }
.vitals__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
  background: var(--surface-1);
  padding: 0.72rem 0;
  font-size: 0.75rem;
}
.vitals__row .k { color: var(--fg-3); letter-spacing: 0.05em; }
.vitals__row .v { color: var(--fg); font-variant-numeric: tabular-nums; }
.vitals__row .v[data-zero="true"] { color: var(--accent); }

.vitals__foot {
  margin-top: 1.2rem; padding-top: 1.1rem;
  border-top: 1px solid var(--hair);
  font-size: var(--t-micro); line-height: 1.6; color: var(--fg-3);
  font-family: var(--f-display); letter-spacing: 0;
}

/* ======================================================= CHI SONO */

.about__body { display: grid; gap: var(--sp-6); }
.about__body p { color: var(--fg-2); max-width: var(--measure); }
.about__body p + p { margin-top: 1.1rem; }

.about h2 { font-size: var(--t-h2); }

.facts {
  margin-top: clamp(3.5rem, 7vw, 6rem);
  border-top: 1px solid var(--hair);
}
.fact {
  display: grid;
  gap: 0.5rem 2rem;
  padding-block: clamp(1.5rem, 3vw, 2.2rem);
  border-bottom: 1px solid var(--hair);
  transition: background-color var(--d-mid) var(--e-out);
}
@media (min-width: 860px) {
  .fact { grid-template-columns: 5rem minmax(0, 12rem) minmax(0, 1fr); align-items: baseline; }
}
.fact:hover { background: var(--accent-soft); }
.fact__k {
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3);
}
.fact__v { font-size: var(--t-h4); font-weight: 500; letter-spacing: -0.025em; line-height: 1.2; }
.fact__sub { font-size: var(--t-small); color: var(--fg-2); max-width: 56ch; }

/* ======================================================= SERVIZI */

.svc { border-top: 1px solid var(--hair); }

.svc__item { border-bottom: 1px solid var(--hair); }

.svc__head {
  display: grid;
  grid-template-columns: 3.5rem minmax(0, 1fr) 2.75rem;
  align-items: center;
  gap: 1rem;
  width: 100%;
  padding-block: clamp(1.6rem, 3.4vw, 2.6rem);
  text-align: left;
}
@media (min-width: 900px) {
  .svc__head { grid-template-columns: 5rem minmax(0, 1.1fr) minmax(0, 1fr) 2.75rem; gap: 2rem; }
}
.svc__num { font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.14em; color: var(--fg-3); transition: color var(--d-mid) var(--e-out); }
.svc__title {
  font-size: var(--t-h3); font-weight: 500; letter-spacing: -0.035em; line-height: 1.05;
  transition: transform var(--d-hover) var(--e-glide);
}
.svc__lead { display: none; font-size: var(--t-small); color: var(--fg-2); }
@media (min-width: 900px) { .svc__lead { display: block; } }

.svc__toggle {
  justify-self: end;
  display: grid; place-items: center;
  width: 2.75rem; height: 2.75rem;
  border: 1px solid var(--hair-2); border-radius: 50%;
  transition: background-color var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
.svc__toggle::before, .svc__toggle::after {
  content: ""; position: absolute;
  width: 11px; height: 1.5px; background: var(--fg);
  transition: transform var(--d-mid) var(--e-spring);
}
.svc__toggle::after { transform: rotate(90deg); }

.svc__item:hover .svc__num { color: var(--fg-2); }
.svc__item:hover .svc__toggle { background: var(--accent-soft); border-color: var(--hair-3); }
@media (hover: hover) and (pointer: fine) {
  .svc__item:hover .svc__title { transform: translateX(6px); }
}
.svc__item.is-open .svc__toggle::after { transform: rotate(180deg); }

/* grid-template-rows 0fr → 1fr animates height without measuring it.
   Authored OPEN: collapsing is something JavaScript does, so without
   it the deliverables are still on the page instead of sealed behind
   a toggle that nothing can operate. */
.svc__panel {
  display: grid; grid-template-rows: 1fr;
  /* This animates a layout property, which is the price of animating to
     an unknown height without measuring it. 820ms of layout work per
     toggle was paying that price four times longer than necessary. */
  transition: grid-template-rows var(--d-panel) var(--e-glide);
}
.js .svc__item:not(.is-open) .svc__panel { grid-template-rows: 0fr; }
.svc__panel > div { overflow: hidden; }

.svc__inner {
  padding-bottom: clamp(2rem, 4vw, 3rem);
  transition: opacity var(--d-panel) var(--e-out) 40ms;
}
.js .svc__item:not(.is-open) .svc__inner { opacity: 0; }
@media (min-width: 900px) { .svc__inner { padding-left: 7rem; } }

.svc__leadm { font-size: var(--t-lead); color: var(--fg-2); max-width: 52ch; margin-bottom: 2rem; }
@media (min-width: 900px) { .svc__leadm { display: none; } }

.svc__list { display: grid; gap: 1px; background: var(--hair); border-block: 1px solid var(--hair); }
@media (min-width: 760px) { .svc__list { grid-template-columns: 1fr 1fr; } }
.svc__list li {
  background: var(--bg);
  display: flex; gap: 0.9rem;
  padding: 1.05rem 1.1rem 1.05rem 0;
  font-size: var(--t-small); color: var(--fg-2);
}
@media (min-width: 760px) { .svc__list li:nth-child(even) { padding-left: 1.4rem; } }
.svc__list li::before {
  content: ""; flex: 0 0 auto;
  width: 5px; height: 5px; margin-top: 0.62em;
  border-radius: 50%; background: var(--accent); opacity: 0.55;
}

/* ===================================================== PORTFOLIO */

/* Each plate declares its own accent. The observer in js/ui.js
   copies the active plate's accent onto <html> so the nav, the rail
   and every button follow the work currently on screen — then hand
   it back to neutral. This is the whole thesis of the design. */

/* A project is a plate hung on the wall, not a repaint of the wall.

   Running each panel full-bleed meant the shell disappeared the moment
   a project arrived — so the page cut from black to cream on a hard
   horizontal edge, and the frame that the whole design is named after
   was gone for the length of the project. Insetting the panel keeps
   the neutral surface visible down both sides and between projects.

   The panel is then built as a mounted print: an outer mat in a middle
   tone, and the project's own surface inside it. That is not
   decoration — it is the only thing that actually fixes the glare.
   Feathering an edge softens the 60px where two fields meet; it cannot
   soften the fact that a large light field sits beside a large dark
   one. A mat can, because it splits one enormous step in luminance
   into two small ones the eye can climb. */
.plate-work {
  --mat-w: clamp(18px, 2.2vw, 40px);
  --r-plate: clamp(20px, 1.6vw, 34px);

  position: relative;
  width: min(100% - var(--gutter) * 2, var(--maxw));
  margin-inline: auto;
  border-radius: var(--r-plate);
  padding: var(--mat-w);
  color: var(--fg);

  /* The mat, darkened toward its own top and bottom so the outer edge
     dissolves into the page instead of ending on a line. */
  background:
    linear-gradient(to bottom,
      rgb(10 10 10 / 0.85) 0,
      rgb(10 10 10 / 0) clamp(30px, 4vw, 60px),
      rgb(10 10 10 / 0) calc(100% - clamp(30px, 4vw, 60px)),
      rgb(10 10 10 / 0.85) 100%),
    var(--mat, #101010);

  /* Ambient bounce: a lit plate throws a little light back onto the
     wall, so the page lifts around the panel rather than meeting it
     at full black. */
  box-shadow: 0 0 clamp(70px, 9vw, 150px) -30px var(--bounce, transparent);
  transition: background-color var(--d-slow) var(--e-glide),
              color var(--d-slow) var(--e-glide);
}
.plate-work + .plate-work { margin-top: clamp(1rem, 1.6vw, 2rem); }

/* The project's own surface, seated inside the mat. `inset: 0` on an
   absolutely positioned child resolves against the padding box, so
   this lands exactly inside the mat with no arithmetic. */
.plate-work::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: calc(var(--r-plate) - var(--mat-w) * 0.6);
  background: var(--bg);
}

/* Content above the surface; both above the mat. */
.plate-work .wrap {
  position: relative;
  z-index: 1;
  max-width: none;
  padding: clamp(2.25rem, 4vw, 4.25rem) clamp(1.25rem, 2.6vw, 3rem);
}

/* Hairline on the outer edge of the mat. */
.plate-work::after {
  content: "";
  position: absolute; inset: 0;
  border-radius: inherit;
  border: 1px solid var(--hair);
  pointer-events: none;
}

.work__grid { display: grid; gap: clamp(2.5rem, 5vw, 4.5rem); align-items: center; }
@media (min-width: 1000px) {
  .work__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
  .work__grid--flip > .work__media { order: 2; }
}

.work__cat {
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3);
  margin-bottom: 1.4rem;
}
.work__title {
  font-size: var(--t-h2); letter-spacing: -0.045em; line-height: 0.95;
  margin-bottom: 1.6rem;
}
.work__body { color: var(--fg-2); max-width: 54ch; font-size: var(--t-body); }
.work__actions { display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: center; margin-top: 2.2rem; }

.work__media { position: relative; }
.work__media .plate__core { aspect-ratio: 4 / 3; }

/* Two transforms, two elements. <picture> takes the hover zoom and the
   <img> inside it takes the scroll parallax further down — stacking
   both on the same element would mean one silently overwriting the
   other. <picture> is a real box, so this costs no extra markup. */
.work__media picture {
  display: block; width: 100%; height: 100%;
  transition: transform 700ms var(--e-glide);
}
.work__media img { width: 100%; height: 100%; object-fit: cover; }

@media (hover: hover) and (pointer: fine) {
  .work__media:hover picture { transform: scale(1.035); }
}

.work__tag {
  position: absolute; left: 1.4rem; bottom: 1.4rem;
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.5rem 0.9rem;
  border-radius: var(--r-pill);
  background: color-mix(in oklab, var(--bg) 62%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--hair-2);
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-2);
}

/* Uneven: bone/steel drawn out of its own campaign imagery.
   The surface is lighter than the page rather than darker — a panel
   blacker than the wall behind it reads as a hole, not an object.
   Its mat barely differs from the page: a dark panel on a dark page
   has no step to bridge. */
.plate-work[data-theme="uneven"] {
  --accent: #cfc8bd;
  --accent-soft: rgb(207 200 189 / 0.12);
  --bg: #141312;
  --mat: #0f0e0d;
  --bounce: rgb(207 200 189 / 0.10);
}

/* Fantasy: a dark panel like the one above it, carrying the project's
   green rather than its cream.

   The green had to be lifted out of the project's own #1f3a2e. That
   value is a forest green meant for dark ink on a cream page; dropped
   onto a dark panel it separates from the surface by 1.5:1 and simply
   disappears. #40705a is the same hue raised until the button clears
   3:1 against the panel and carries white text at 5.7:1. */
.plate-work[data-theme="fantasy"] {
  --bg: #121614;
  --mat: #0e100f;
  --surface-1: #171c19;
  --accent: #40705a;
  --accent-ink: #ffffff;
  --accent-soft: rgb(64 112 90 / 0.16);
  --bounce: rgb(64 112 90 / 0.14);
}

/* ======================================================= CTA BAND */

.band { padding-block: clamp(5rem, 10vw, 9rem); border-top: 1px solid var(--hair); }
.band__grid { display: grid; gap: var(--sp-6); align-items: end; }
@media (min-width: 900px) { .band__grid { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: var(--sp-8); } }
.band h2 { font-size: var(--t-h2); max-width: 18ch; }
.band__sub { font-size: var(--t-small); color: var(--fg-2); max-width: 34ch; margin-bottom: 1.5rem; }
.band__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

/* ======================================================= CONTATTI */

.contact__grid { display: grid; gap: clamp(3rem, 6vw, 5rem); align-items: start; }
@media (min-width: 1000px) { .contact__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); } }

.contact h2 { font-size: var(--t-h2); margin-bottom: 1.6rem; }

.contact__bullets { margin-top: 2.5rem; border-top: 1px solid var(--hair); }
.contact__bullets li {
  display: flex; gap: 1rem; align-items: flex-start;
  padding-block: 1.05rem;
  border-bottom: 1px solid var(--hair);
  font-size: var(--t-small); color: var(--fg-2);
}
.contact__bullets .num { padding-top: 0.25em; }

.contact__aux { display: grid; gap: 1.5rem; margin-top: 2.5rem; }
@media (min-width: 520px) { .contact__aux { grid-template-columns: 1fr 1fr; } }
.contact__aux dt {
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 0.45rem;
}
.contact__aux dd { font-size: var(--t-small); }

/* ------------------------------------------------------------ Form */

.form .plate__core { padding: clamp(1.5rem, 3.5vw, 2.5rem); }

.form__top {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding-bottom: 1.4rem; border-bottom: 1px solid var(--hair); margin-bottom: 2rem;
}
.form__step-n { font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.16em; text-transform: uppercase; color: var(--fg-3); }
.form__dots { display: flex; gap: 0.4rem; }
.form__dots span {
  width: 26px; height: 2px; border-radius: 2px; background: var(--hair-2);
  transition: background-color var(--d-mid) var(--e-out);
}
.form__dots span.is-on { background: var(--accent); }

.form h3 { font-size: var(--t-h4); margin-bottom: 0.6rem; }
.form__hint { font-size: var(--t-small); color: var(--fg-3); margin-bottom: 2rem; }

.form__fields { display: grid; gap: 1.6rem; }
@media (min-width: 620px) { .form__fields { grid-template-columns: 1fr 1fr; } .field--full { grid-column: 1 / -1; } }

/* Underlined fields, not boxes — closer to a printed form. */
.field { position: relative; }
.field label {
  display: block;
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--fg-3); margin-bottom: 0.65rem;
  transition: color var(--d-fast) var(--e-out);
}
.field input, .field textarea {
  width: 100%;
  padding: 0 0 0.7rem;
  background: transparent;
  border: 0; border-bottom: 1px solid var(--hair-2);
  border-radius: 0;
  font-size: var(--t-body);
  transition: border-color var(--d-fast) var(--e-out);
}
.field textarea { resize: vertical; min-height: 5.5rem; line-height: 1.55; }
.field input::placeholder, .field textarea::placeholder { color: var(--fg-4); }
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--accent); }
.field:focus-within label { color: var(--fg-2); }
.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea { border-bottom-color: #ff8f7a; }

.field__err {
  display: block; margin-top: 0.5rem;
  font-size: var(--t-micro); color: #ff8f7a;
  min-height: 1em;
}

.check {
  display: flex; gap: 0.85rem; align-items: flex-start;
  margin-top: 2rem; cursor: pointer;
  font-size: var(--t-small); color: var(--fg-2);
}
.check input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.check__box {
  flex: 0 0 auto;
  display: grid; place-items: center;
  width: 20px; height: 20px; margin-top: 0.15em;
  border: 1px solid var(--hair-2); border-radius: 6px;
  transition: background-color var(--d-fast) var(--e-out), border-color var(--d-fast) var(--e-out);
}
.check__box svg { width: 11px; height: 11px; opacity: 0; transform: scale(0.6); color: var(--accent-ink); transition: opacity var(--d-fast) var(--e-out), transform var(--d-fast) var(--e-spring); }
.check input:checked + .check__box { background: var(--accent); border-color: var(--accent); }
.check input:checked + .check__box svg { opacity: 1; transform: none; }
.check input:focus-visible + .check__box { outline: 2px solid var(--accent); outline-offset: 3px; }

.form__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 2.2rem; }
.form__err-global { font-size: var(--t-small); color: #ff8f7a; margin-top: 1rem; }

/* Review step */
.review { display: grid; gap: 1px; background: var(--hair); border-block: 1px solid var(--hair); }
.review__row { display: grid; gap: 0.3rem; background: var(--surface-1); padding: 0.95rem 0; }
@media (min-width: 520px) { .review__row { grid-template-columns: 8rem minmax(0, 1fr); gap: 1.5rem; align-items: baseline; } }
.review__k { font-family: var(--f-mono); font-size: var(--t-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-3); }
.review__v { font-size: var(--t-small); overflow-wrap: anywhere; }
.review__v:empty::after { content: "—"; color: var(--fg-4); }

.form__pane[hidden] { display: none; }

.form__success { text-align: left; padding-block: 1rem; }
.form__success .tick {
  display: grid; place-items: center;
  width: 3rem; height: 3rem; margin-bottom: 1.6rem;
  border-radius: 50%; background: var(--accent); color: var(--accent-ink);
}
.form__success h3 { font-size: var(--t-h3); margin-bottom: 0.9rem; }
.form__success p { color: var(--fg-2); font-size: var(--t-small); max-width: 46ch; margin-bottom: 2rem; }

/* ========================================================= FOOTER */

.footer { border-top: 1px solid var(--hair); padding-top: clamp(4rem, 8vw, 7rem); padding-bottom: 2.5rem; }

.footer__mark {
  font-size: var(--t-mega);
  font-weight: 600; letter-spacing: -0.06em; line-height: 0.82;
  color: var(--fg);
  /* A line-height of 0.82 on 152px type leaves the descender of the
     "g" hanging ~30px outside the element's own box. That makes the
     box lie about the type's real height — which throws off the space
     below it and, worse, lets any clip-path cut the tail off "Sega".
     Padding the box to fit the ink fixes both at the source. */
  padding-bottom: 0.21em;
  margin-bottom: clamp(3rem, 7vw, 5.5rem);
}
.footer__mark span { color: var(--fg-4); }

.footer__grid { display: grid; gap: var(--sp-6); }
@media (min-width: 800px) { .footer__grid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-7); } }

.footer__tagline { font-size: var(--t-small); color: var(--fg-2); max-width: 38ch; }
.footer h4 {
  font-family: var(--f-mono); font-size: var(--t-micro);
  font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fg-3); margin-bottom: 1.2rem;
}
.footer__list li + li { margin-top: 0.8rem; }
.footer__list a { font-size: var(--t-small); color: var(--fg-2); transition: color var(--d-fast) var(--e-out); }
.footer__list a:hover { color: var(--fg); }

.footer__bottom {
  display: flex; flex-wrap: wrap; gap: 1rem 2rem; justify-content: space-between;
  margin-top: clamp(3rem, 6vw, 5rem); padding-top: 1.6rem;
  border-top: 1px solid var(--hair);
  font-family: var(--f-mono); font-size: var(--t-micro);
  letter-spacing: 0.08em; color: var(--fg-3);
}

/* The glossary entry point: a full-width invitation, not a footnote. */
.glossary-cue {
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  width: 100%;
  padding: clamp(1.5rem, 3vw, 2.1rem) clamp(1.2rem, 3vw, 2rem);
  border: 1px solid var(--hair); border-radius: var(--r-out);
  text-align: left;
  transition: background-color var(--d-hover) ease,
              border-color var(--d-hover) ease,
              transform var(--d-press) var(--e-out);
}
.glossary-cue:hover { background: var(--accent-soft); border-color: var(--hair-2); }
.glossary-cue__t { font-size: var(--t-body); font-weight: 500; }
.glossary-cue__s { font-size: var(--t-small); color: var(--fg-3); margin-top: 0.3rem; }
.glossary-cue .btn__ico { background: var(--accent-soft); }
.glossary-cue:hover .btn__ico { transform: translate(2px, -2px) scale(1.06); }


/* ============================================ MOTION — STAGGER */

/* Six deliverables arriving as one block reads as a chunk of text
   appearing. A 45ms step turns it into a list being written out; the
   whole run still finishes inside 500ms, so nothing is waiting on it. */
.svc__list li {
  transition: opacity var(--d-panel) var(--e-out),
              transform var(--d-panel) var(--e-out);
}
.js .svc__item:not(.is-open) .svc__list li {
  opacity: 0;
  transform: translateY(10px);
}
.svc__item.is-open .svc__list li:nth-child(1) { transition-delay:  70ms; }
.svc__item.is-open .svc__list li:nth-child(2) { transition-delay: 115ms; }
.svc__item.is-open .svc__list li:nth-child(3) { transition-delay: 160ms; }
.svc__item.is-open .svc__list li:nth-child(4) { transition-delay: 205ms; }
.svc__item.is-open .svc__list li:nth-child(5) { transition-delay: 250ms; }
.svc__item.is-open .svc__list li:nth-child(6) { transition-delay: 295ms; }

/* ======================================= MOTION — PAGE ENTRANCE */

/* The chrome arrives a beat before the headline it frames. Short, once
   per visit, and `both` so nothing flashes at full opacity first. */
@keyframes chrome-in {
  from { opacity: 0; transform: translateY(-9px); }
}
.nav__inner { animation: chrome-in 620ms var(--e-out) both; }

@keyframes rail-in {
  from { opacity: 0; transform: translateX(-10px); }
}
.rail a { animation: rail-in 560ms var(--e-out) both; }
.rail a:nth-child(1) { animation-delay: 300ms; }
.rail a:nth-child(2) { animation-delay: 360ms; }
.rail a:nth-child(3) { animation-delay: 420ms; }
.rail a:nth-child(4) { animation-delay: 480ms; }
.rail a:nth-child(5) { animation-delay: 540ms; }

/* ===================================== MOTION — SCROLL-DRIVEN */

/* Native scroll-driven animations. These run on the compositor, need
   no scroll listener, no rAF loop and no library — and where the
   browser doesn't support them the elements simply sit at their rest
   state, which is the finished look. That is why the whole block can
   live behind @supports with no fallback path. */

.scroll-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: var(--z-nav);
  pointer-events: none;
}
.scroll-progress span {
  display: block;
  height: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
  /* It borrows the accent like the rest of the chrome, so the progress
     line is the project's colour while that project is on screen. */
  transition: background-color var(--d-slow) var(--e-glide);
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes progress-grow { to { transform: scaleX(1); } }
    .scroll-progress span {
      animation: progress-grow linear both;
      animation-timeline: scroll(root block);
    }
  }
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* The photograph drifts against its frame as the plate crosses the
       viewport. The 1.09 scale is the overscan that keeps the ±4%
       travel from exposing an edge. */
    @keyframes plate-parallax {
      from { transform: translate3d(0, -4%, 0) scale(1.09); }
      to   { transform: translate3d(0,  4%, 0) scale(1.09); }
    }
    .work__media img {
      animation: plate-parallax linear both;
      animation-timeline: view();
      animation-range: entry 0% exit 100%;
    }

    /* The wordmark wipes in rather than fading: at this size a fade
       reads as the page still loading.

       The insets are negative on the vertical axis on purpose. With
       line-height 0.82 the descender of the "g" hangs ~30px below the
       element's own box, and `inset(0 …)` clips to that box — which
       cut the tail clean off "Sega". A clip that only ever moves
       horizontally has no business trimming the type. */
    @keyframes mark-wipe {
      from { clip-path: inset(0 100% 0 0); }
      to   { clip-path: inset(0 -2% 0 0); }
    }
    .footer__mark {
      animation: mark-wipe linear both;
      animation-timeline: view();
      animation-range: entry 15% cover 25%;
    }
  }
}


/* ============================= CASE STUDY — extras for Fantasy */

/* The catalogue montages are wide strips, not 4:3 plates. Letting the
   image set its own height stops `object-fit: cover` from cropping the
   outer products out of the composition. */
.cs__figures .is-strip .plate__core { aspect-ratio: auto; }
.cs__figures .is-strip img { height: auto; }

/* Technology list: facts, so they read as chips rather than prose. */
.cs__tags { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.cs__tags li {
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--hair-2);
  border-radius: var(--r-pill);
  font-family: var(--f-mono);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  color: var(--fg-2);
}

/* A project with an external link needs the row to wrap on a phone
   without the link and the meta colliding. */
.work__actions { row-gap: 1rem; }
