/* ===================================================================
   RESPONSIVE — telefono e schermi bassi
   ===================================================================
   Le scene su un telefono: le griglie diventano binari scorrevoli, la
   ruota laterale diventa la ruota nella barra, il gesto passa dalla
   rotella al pollice. In fondo i casi stretti — il telefono basso e il
   telefono coricato.

   ATTENZIONE ALL'ORDINE
   Questi quattro file erano un solo css/style.css da 1615 righe, tagliato
   in sequenza il 04/09/2026: nessuna riga e' stata spostata rispetto alle
   altre, ne' riscritta. Nel CSS, a parita' di specificita', vince chi
   arriva dopo — quindi in index.html vanno collegati in QUEST'ORDINE e in
   nessun altro:

       base.css  ->  layout.css  ->  scene.css  ->  responsive.css

   Invertirne due cambia quale regola vince, e rompe la pagina in punti
   difficili da ricollegare alla causa.
   =================================================================== */

/* ===================================================================
   SCENE MODE ON A PHONE
   ===================================================================
   Scene mode is the page's only layout now, on every screen. What changes
   below the desktop breakpoint is not whether the panels exist but how they
   are dressed: the side wheel becomes a wheel in the bar, the card GRIDS
   become card RAILS, and the gesture changes hands from a mouse wheel to a
   thumb.

   Everything here overrides the block above rather than repeating it, so a
   token or a rule that needs no phone-specific value simply is not mentioned. */
@media (max-width: 980px) {

  /* --- The box ---------------------------------------------------------- */

  /* svh, not vh. On iOS Safari vh is the height the viewport has with the
     browser chrome RETRACTED, so a pinned 100vh panel is taller than what is
     on screen for as long as the bars are showing, and the foot of every
     panel sits behind them. svh is the small viewport — the one that is
     always visible — which is exactly the guarantee scene mode is making.
     Declared after the vh rule above, so a browser without svh keeps that. */
  body.scene-mode-ready .scene-track,
  body.scene-mode-ready .scene-stage { height: 100svh; }

  /* The bar stays on screen here — it IS the navigation (see .nav-wheel-bar
     in css/option-wheel.css), where on desktop the fixed rail does that job
     and the bar is hidden. So every panel starts below it, and the height is
     measured and published by js/main.js rather than guessed, because it
     depends on what the bar ends up holding. */
  body.scene-mode-ready main .scene {
    padding-top: calc(var(--sc-pad-block) + var(--navbar-h, 64px));
  }

  /* Type is sized against the viewport's HEIGHT everywhere else, which is the
     right axis on a laptop — the panel is short and wide. A phone is the
     other shape entirely: 844px of height is generous and 390px of width is
     not, so on a phone the headings have to be measured against the width, or
     a 39px heading arrives on a screen that fits nine of its characters. */
  body.scene-mode-ready .scene {
    --sc-h2:         clamp(23px, 6.2vw, 34px);
    --sc-hero-title: clamp(34px, 10.6vw, 58px);
    --sc-cta-title:  clamp(25px, 7.4vw, 40px);
    --sc-card-h3:    clamp(17px, 4.8vw, 22px);
    --sc-proj-h3:    clamp(16px, 4.6vw, 21px);
    --sc-lead:       clamp(17px, 4.6vw, 21px);

    /* How far the rails bleed past the panel's own padding — see below. */
    --sc-edge: 22px;
  }

  /* --- The gestures ----------------------------------------------------- */

  /* Nothing on this page scrolls natively while it is pinned: the swipe
     handler in js/main.js reads the gesture and turns the page itself. Saying
     so up front is not a micro-optimisation — until a touch-action tells it
     otherwise, the browser spends the first stretch of every gesture deciding
     whether IT owns the scroll, and the page answers late and feels heavy.

     overscroll-behavior is the other half: without it the whole pinned stage
     rubber-bands against a scroll that cannot happen. */
  body.scene-pinned { overscroll-behavior: none; }
  body.scene-mode-ready .scene-inner { touch-action: none; }

  /* ...unless a panel genuinely did not fit. js/main.js marks those after it
     has measured them, and only then is a vertical drag inside the panel the
     browser's business again. In practice nothing carries this class today —
     it is what keeps a future overlong section readable instead of trapped. */
  body.scene-mode-ready .scene--scrolls .scene-inner { touch-action: pan-y; }

  /* --- Card rails ------------------------------------------------------- */

  /* The three panels that hold more than one card become one-card-at-a-time
     rails: a vertical swipe still turns the page, a horizontal one walks the
     cards. Both #servizi (five cards) and #progetti (three) were 2 to 3.6
     TIMES the height of a phone screen when stacked, which no amount of
     shrinking was going to fix — and #chi-sono is the same problem in another
     shape, a portrait card and a page of prose that only fit side by side.

     Native overflow scrolling with snap points, not a JS carousel: it keeps
     the platform's own momentum and rubber-band, it is reachable by keyboard
     and screen reader as an ordinary scroll container, and it costs nothing
     while the rail is off screen. js/main.js only adds the dots underneath.

     touch-action: pan-x is what divides the two gestures. It tells the browser
     this box handles horizontal panning and nothing else, so a vertical drag
     that starts on a card is never swallowed here — it reaches the page
     handler and turns the section, which is what the finger meant. */
  body.scene-mode-ready .feature-grid,
  body.scene-mode-ready .projects-grid,
  body.scene-mode-ready .about-grid {
    display: flex;
    grid-template-columns: none;
    align-items: stretch;
    gap: var(--sc-grid-gap);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    touch-action: pan-x;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    /* Bleed out to the screen edges so the next card peeks in and the rail
       reads as something to swipe, then pad the same amount back so the first
       card still lines up with the heading above it. */
    margin-inline: calc(-1 * var(--sc-edge));
    padding-inline: var(--sc-edge);
    scroll-padding-inline: var(--sc-edge);
  }
  body.scene-mode-ready .feature-grid::-webkit-scrollbar,
  body.scene-mode-ready .projects-grid::-webkit-scrollbar,
  body.scene-mode-ready .about-grid::-webkit-scrollbar { display: none; }

  /* The peek is the point — it is what says the rail can be swiped — but a
     card sliced down the middle by the edge of the screen reads as a bug, not
     as an invitation, and on the prose slide of #chi-sono it was cutting words
     in half. Fading the last few pixels turns the same sliver into something
     that is obviously continuing rather than something broken.

     The mask is anchored to the rail's border box, not to its content, so it
     stays welded to the screen edges while the cards travel under it. */
  body.scene-mode-ready .feature-grid,
  body.scene-mode-ready .projects-grid,
  body.scene-mode-ready .about-grid {
    /* The fade has to be as wide as the sliver it is softening, not as wide as
       the bleed: a card at 85% of the rail leaves about 2x --sc-edge of the
       next one showing past the active card's edge, and a narrower gradient
       left most of that sliver sharp with only its last few pixels dimmed —
       which reads as a cut with a shadow on it rather than as a fade. */
    -webkit-mask-image: linear-gradient(to right, transparent 0,
      #000 calc(var(--sc-edge) * 2), #000 calc(100% - var(--sc-edge) * 2), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0,
      #000 calc(var(--sc-edge) * 2), #000 calc(100% - var(--sc-edge) * 2), transparent 100%);
  }

  body.scene-mode-ready .feature-grid > *,
  body.scene-mode-ready .projects-grid > *,
  body.scene-mode-ready .about-grid > * {
    /* Not 100%: the sliver of the next card showing past the edge is the only
       thing on screen that says the rail can be swiped at all. */
    flex: 0 0 min(85%, 360px);
    scroll-snap-align: center;
  }

  /* The about panel's two halves are wider than a service card — one holds a
     portrait, the other a page of prose.

     88% and not 92%: the slide is centred in the rail, so its own edges land
     at (100% - basis) / 2 from either side, and the fade above eats the outer
     2 x --sc-edge. At 88% those two numbers meet almost exactly — the slide
     stops right where the gradient starts, so the sliver of the NEXT slide is
     entirely inside the fade and this one is entirely outside it. Any wider
     and the fade starts dimming the sentence the reader is on. */
  body.scene-mode-ready .about-grid > * { flex-basis: min(88%, 400px); }
  body.scene-mode-ready .about-side { align-items: center; text-align: center; }
  body.scene-mode-ready .about-side .section-header.align-left { text-align: center; }

  /* --- Rail dots -------------------------------------------------------- */

  /* Built by js/main.js, one per card. They are a position indicator first and
     a control second: on a rail this short, tapping a dot is a convenience,
     but knowing there are five cards and that this is the second is the thing
     the reader actually needs and cannot otherwise see. */
  .rail-dots {
    display: flex;
    justify-content: center;
    gap: 9px;
    margin-top: var(--sc-grid-gap, 16px);
  }
  .rail-dots__dot {
    width: 7px;
    height: 7px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(235, 235, 235, 0.22);
    transition: background 0.35s var(--ease), transform 0.35s var(--ease);
    /* The dot is 7px; the tap target has to be a finger wide. A transparent
       outline costs no layout and gives it 23px without moving anything. */
    outline: 8px solid transparent;
    cursor: pointer;
  }
  .rail-dots__dot[aria-current="true"] {
    background: var(--accent);
    transform: scale(1.35);
  }

  /* --- Panels that need a little more than tokens ------------------------ */

  /* Stacked on a phone: the notes sit above the reel instead of beside it, so
     the reel gets what is left rather than the whole panel — see
     resultsHeightBudget in js/main.js, which subtracts everything the panel
     holds except the reel itself. */
  body.scene-mode-ready .results-layout { max-width: none; }

  /* The final panel is a heading and a button; it centres on its own, and the
     stacked-flow paddings would only push it off centre. */
  body.scene-mode-ready .final-cta { padding-inline: 24px; }
}

/* The rails only exist below the breakpoint; above it the same markup is the
   three-column grid it has always been, and the dots would be a control for a
   rail that is not there. */
@media (min-width: 981px) {
  .rail-dots { display: none; }
}

/* ===== Phone: the last three panels =====
   Appended after the block above, so these override it.

   Everything here came out of measuring the panels on a real phone viewport
   rather than reasoning about them, and each rule below is one measured
   number: the project paragraph running to eight lines, the reel hitting the
   floor of its own scale, and the headings being sized against a width that
   is enormous the moment the phone is turned on its side. */
@media (max-width: 980px) {

  /* Type was measured against the WIDTH here, which is right for a phone held
     upright and badly wrong the moment it is turned: 844px of width against
     390px of height asked for a 52px heading on a screen with room for about
     four lines of anything. min() takes whichever axis is scarcer, so the
     portrait numbers are untouched and landscape stops asking for the
     impossible. */
  body.scene-mode-ready .scene {
    --sc-h2:         clamp(22px, min(6.2vw, 8.2vh), 34px);
    --sc-hero-title: clamp(32px, min(10.6vw, 10vh), 58px);
    --sc-cta-title:  clamp(24px, min(7.4vw, 9.5vh), 40px);
    --sc-card-h3:    clamp(16px, min(4.8vw, 6.4vh), 22px);
    --sc-proj-h3:    clamp(15px, min(4.6vw, 6vh), 21px);
    --sc-lead:       clamp(16px, min(4.6vw, 6vh), 21px);
  }

  /* The project card's paragraph was clamped to three lines on a short laptop
     and nowhere else, which left it running to EIGHT on a phone — 177px of a
     card that only had about 430 to give, and the tag row underneath fell off
     the panel because of it. The reasoning that applied to the laptop applies
     twice over here: the full text is still in the DOM for search engines and
     assistive tech, and the reader gets all of it in the full-screen stage
     that a tap opens. */
  body.scene-mode-ready .project-card > p {
    /* Clamped with max-height and not with -webkit-line-clamp, which draws an
     ellipsis of its own at the truncation point. There is already one there:
     js/text-peek.js puts an amber one at the end of the line as the control
     that opens the full text, and the browser's grey one landed a few words
     to its left — two ellipses on one line, which reads as a mistake. This
     caps the same number of lines and draws nothing. */
    /* Cinque righe e non piu' tre: le tre pastiglie qui sotto sono state
       nascoste e quello spazio — una ottantina di pixel — torna al testo,
       che e' la cosa che il lettore era venuto a leggere. I tre puntini
       restano: sono di js/text-peek.js e aprono il testo intero. */
    max-height: calc(5 * 1lh);
    overflow: hidden;
  }

  /* La riga del titolo con "push", le pastiglie nascoste e la vecchia scritta
     nell'anteprima non stanno piu' qui: valgono a ogni larghezza, e sono in
     css/layout.css e css/scroll-expand.css. Di specifico del telefono resta
     soltanto quante righe di testo ci stanno, qui sopra. */

  /* ===== Risultati =====
     The reel and its note stack here instead of sitting side by side, so for
     the first time they are competing for the same vertical budget rather
     than sharing a row. The reel is the section — a 9:16 video shown much
     below about 200px wide stops being watchable — so the note is what gives.

     Four lines at a size that still reads as the serif pull-quote it is on
     desktop. As everywhere else on this page, the text is clamped and not
     cut: all four notes stay whole in the markup. */
  body.scene-mode-ready .brand-note__text {
    font-size: clamp(14.5px, 4vw, 17px);
    line-height: 1.5;
    max-width: none;
    /* Clamped with max-height and not with -webkit-line-clamp, which draws an
     ellipsis of its own at the truncation point. There is already one there:
     js/text-peek.js puts an amber one at the end of the line as the control
     that opens the full text, and the browser's grey one landed a few words
     to its left — two ellipses on one line, which reads as a mistake. This
     caps the same number of lines and draws nothing. */
    max-height: calc(4 * 1lh);
    overflow: hidden;
  }
  body.scene-mode-ready .brand-note__brand { margin-bottom: 8px; }
  body.scene-mode-ready .results-layout { gap: var(--sc-header-gap); }

  /* ===== Chi Sono =====
     Two rail slides: the portrait, then the prose.

     The card is told how tall it may be and never how wide: it derives its
     width from --pc-card-h to hold its 0.718 ratio (see css/profile-card.css),
     so a max-width here would be silently ignored by the thing it is aimed at
     and would only cut the glow that tracks it. */
  /* Piu' grande di prima (era clamp(240px, 38svh, 360px)), e non e' una
     preferenza: da quando il testo interno segue la card — vedi la nota su
     font-size in css/profile-card.css — una card piccola vuol dire scritte
     piccole. A 38svh il ruolo veniva 9px e il pulsante 8: leggibili sullo
     schermo di un computer, non in mano.

     Lo spazio c'era gia': la griglia di "Chi Sono" e' alta 600px su uno
     schermo da 844 e la card ne usava 320. */
  body.scene-mode-ready #profileCardHost .pc-card-wrapper {
    --pc-card-h: clamp(280px, 46svh, 420px);
  }

  /* The three facts are the most scannable thing in the panel and the reason
     they were costing 233px of it was the layout, not the content: a label and
     a value on one row, in a column 300px wide, put both of them onto two
     lines each. Stacked they are three tight pairs. */
  body.scene-mode-ready .fact {
    flex-direction: column;
    align-items: flex-start;
    gap: 1px;
  }
  body.scene-mode-ready .fact-value { text-align: left; font-size: 15px; }
  body.scene-mode-ready .about-content p {
    /* Clamped with max-height and not with -webkit-line-clamp, which draws an
     ellipsis of its own at the truncation point. There is already one there:
     js/text-peek.js puts an amber one at the end of the line as the control
     that opens the full text, and the browser's grey one landed a few words
     to its left — two ellipses on one line, which reads as a mistake. This
     caps the same number of lines and draws nothing. */
    max-height: calc(4 * 1lh);
    overflow: hidden;
  }
  body.scene-mode-ready .about-lead { max-height: calc(3 * 1lh); }
  /* The facts block is three short rows and the most scannable thing in the
     panel; it keeps its place while the prose above it gives way. */
  body.scene-mode-ready .about-facts {
    margin-top: var(--sc-prose-gap);
    padding-top: var(--sc-prose-gap);
  }
}

/* A phone that is short as well as narrow — a 667px iPhone SE, or any handset
   with the browser's own bars taking their cut. The prose slide of #chi-sono
   is the only panel that does not fit at this size, and one line off each
   paragraph is the whole difference. */
@media (max-width: 980px) and (max-height: 700px) {
  body.scene-mode-ready .about-content p { max-height: calc(3 * 1lh); }
  body.scene-mode-ready .about-lead { max-height: calc(2 * 1lh); }
}

/* ===== A phone on its side =====
   The hard case on this page, and worth saying why: turning the phone takes
   the axis scene mode spends — height — from 844px down to 390, and the bar
   at the top is charged against that smaller number, not the larger one. At
   the sizes the rest of this stylesheet uses, the bar alone was eating 80px of
   a 390px screen and the panels were left about 270px to work in.

   So this is not a smaller version of the portrait layout, it is a leaner one:
   the bar shows the current section only, the headings are measured against
   the height, and the two longest pieces of copy give up a couple of lines
   each. Everything is still there and still one panel per screen. */
@media (max-width: 980px) and (max-height: 500px) {

  /* One row, not three. The section either side of this one is a nicety; the
     44px it costs, on a screen this short, is not.

     La misura sta sul contenitore, non piu' sulla ruota: e' lui il pezzo che
     la barra dispone, e il bersaglio invisibile del menu si stende su di lui.
     Scrivendola sulla ruota, il bersaglio sarebbe rimasto alto 64px sopra una
     ruota alta 26 — cioe' premibile anche dove non c'era piu' niente. */
  body.nav-bar-wheel-ready .nav-wheel-trigger { height: 26px; }
  body.nav-bar-wheel-ready .nav-inner { padding: 5px 16px; }
  body.nav-bar-wheel-ready .logo-icon { width: 28px; height: 28px; }
  body.nav-bar-wheel-ready .logo-word { font-size: 14px; }

  body.scene-mode-ready .scene {
    --sc-h2:         clamp(20px, min(6.2vw, 8vh), 30px);
    --sc-hero-title: clamp(26px, min(10.6vw, 8.4vh), 44px);
    --sc-cta-title:  clamp(22px, min(7.4vw, 8vh), 34px);
  }
  body.scene-mode-ready .section-header h2 { line-height: 1.05; }

  /* The hero's second paragraph and the service cards' bodies are the two
     places with lines to spare — both restate, at length, what the heading
     above them has already said in one line. */
  body.scene-mode-ready .hero-body {
    /* Clamped with max-height and not with -webkit-line-clamp, which draws an
     ellipsis of its own at the truncation point. There is already one there:
     js/text-peek.js puts an amber one at the end of the line as the control
     that opens the full text, and the browser's grey one landed a few words
     to its left — two ellipses on one line, which reads as a mistake. This
     caps the same number of lines and draws nothing. */
    max-height: calc(2 * 1lh);
    overflow: hidden;
  }
  body.scene-mode-ready .feature-grid .spotlight-card p {
    /* Clamped with max-height and not with -webkit-line-clamp, which draws an
     ellipsis of its own at the truncation point. There is already one there:
     js/text-peek.js puts an amber one at the end of the line as the control
     that opens the full text, and the browser's grey one landed a few words
     to its left — two ellipses on one line, which reads as a mistake. This
     caps the same number of lines and draws nothing. */
    max-height: calc(3 * 1lh);
    overflow: hidden;
  }

  /* Landscape is the one shape where the reel and its note fit side by side
     again — the screen is wide and there is no height to stack them in. */
  body.scene-mode-ready .results-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 240px);
    gap: 28px;
  }
}

/* ===== A phone on its side, continued =====
   The three panels that hold something with a shape of its own — a
   screenshot, a 9:16 reel, a portrait — cannot be solved by taking lines off
   the copy, because the copy is not what is tall. They are recomposed instead:
   what stacked in portrait sits side by side here, which is the one thing a
   390px-tall, 844px-wide screen is generous about. */
@media (max-width: 980px) and (max-height: 500px) {

  /* The heading block becomes one line. Stacked, an eyebrow over a two-line
     serif heading was 77px of a 310px panel — a quarter of the screen spent
     announcing the section before showing any of it. */
  body.scene-mode-ready .section-header {
    display: flex;
    align-items: baseline;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px 14px;
    margin-bottom: var(--sc-prose-gap);
  }
  body.scene-mode-ready .section-header .eyebrow { margin-bottom: 0; }
  body.scene-mode-ready .section-header h2 { font-size: clamp(17px, 5.4vh, 24px); }
  /* The headings carry their own line breaks for the desktop composition;
     on one line they would break it in half for no reason. */
  body.scene-mode-ready .section-header h2 br { display: none; }

  /* ===== Progetti: the card turns too =====
     Portrait puts the screenshot above the words. Here it goes beside them,
     which halves the card without shrinking either part: the well keeps a
     readable width and the title, blurb and tags fill the column next to it
     instead of queueing underneath. Areas rather than a wrapper element,
     because the card's markup is the same four blocks on every screen and
     adding a div for one orientation would put it in everyone's way. */
  body.scene-mode-ready .projects-grid > * { flex-basis: min(68%, 520px); }
  body.scene-mode-ready .project-card {
    display: grid;
    grid-template-columns: minmax(0, 190px) minmax(0, 1fr);
    grid-template-areas:
      "tag  tag"
      "shot title"
      "shot body"
      "shot tags";
    grid-template-rows: auto auto auto 1fr;
    column-gap: 16px;
  }
  body.scene-mode-ready .project-card > .project-tag { grid-area: tag; }
  body.scene-mode-ready .project-card > .project-preview {
    grid-area: shot;
    margin-bottom: 0;
    align-self: start;
  }
  body.scene-mode-ready .project-card > h3 { grid-area: title; }
  body.scene-mode-ready .project-card > p { grid-area: body; max-height: calc(2 * 1lh); }
  body.scene-mode-ready .project-card > .tag-row { grid-area: tags; align-self: end; }

  /* ===== Risultati: back to a row =====
     Landscape is the one shape where the reel and its note fit beside each
     other again, the way they do on a desktop — there is width to spare and
     no height to stack them in. */
  body.scene-mode-ready .results-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 210px);
    gap: 24px;
    align-items: center;
  }
  body.scene-mode-ready .brand-note__text {
    font-size: clamp(13px, 3.6vh, 16px);
    /* Re-stated because the line height it is measured against just changed:
       max-height in lh follows the element's own leading, and the font-size
       above moves it. */
    max-height: calc(4 * 1lh);
  }

  /* ===== Chi Sono: portrait beside prose =====
     Which is what the desktop does, and what portrait could not: two rail
     slides become one row again. */
  body.scene-mode-ready .about-grid {
    display: grid;
    grid-template-columns: minmax(0, 0.75fr) minmax(0, 1.25fr);
    gap: 24px;
    align-items: center;
    overflow: visible;
    margin-inline: 0;
    padding-inline: 0;
    /* Both halves are on screen at once here, so there is no sliver to soften
       — and the rail's edge fade, left in place, would spend its last 44px
       dimming the end of every line of the prose instead. */
    -webkit-mask-image: none;
            mask-image: none;
  }
  body.scene-mode-ready .about-side { gap: var(--sc-prose-gap); }
  body.scene-mode-ready #profileCardHost .pc-card-wrapper {
    --pc-card-h: clamp(170px, 62svh, 250px);
  }
  body.scene-mode-ready .about-content p { max-height: calc(2 * 1lh); }

  /* The facts strip turns with everything else: three stacked rows, 177px of
     a 310px panel, become three columns of one row. It is the same three
     label/value pairs — nothing is dropped, they are simply laid out along
     the axis this screen has to spare. */
  body.scene-mode-ready .about-facts {
    display: flex;
    gap: 16px;
    margin-top: var(--sc-prose-gap);
    padding-top: var(--sc-prose-gap);
  }
  body.scene-mode-ready .about-facts .fact { flex: 1 1 0; }
  body.scene-mode-ready .fact-value { font-size: 12.5px; line-height: 1.3; }

  /* One row is not a rail, so its dots would be a control for nothing. */
  body.scene-mode-ready .about-grid + .rail-dots { display: none; }
}
