/* ==========================================================================
   The property sheet.

   Rewritten on the approved direction (docs/DESIGN.md): the page is a sequence
   of bands, nothing is centred, and every colour comes from a ROLE TOKEN of
   site.css — never a literal — so the sheet is correct on white, on paper, on
   pale blue, on the two dark grounds and in dark mode without one extra
   selector. The exceptions are deliberate and named in §10 of that document:
   the scrim over the cover photograph and the mono line that sits on it, the
   viewer chrome and the video poster button are fixed white and fixed dark,
   because a photograph does not change with the colour scheme.

   Almost nothing here is new furniture. `.viewer` `.vnav` `.vcount` `.vfull`
   `.thumbs` `.pgrid` `.side` `.pbox` `.q` `.specs` `.sp` `.ebar` `.prose`
   `.stats` `.stat` `.bar` are all site.css components, and what follows mostly
   places them: the page-specific rules are the cover, the stats row's glyphs,
   the thumbnail strip's layout, the energy chip, the video poster and the
   dialog.

   Order: the quiet line above the title, the status band, the cover, the
   narrative and the panel, the data sheet, the gallery, the video, the enquiry,
   the territory, the viewer.
   ========================================================================== */

/* ------------------------------------------- 1. the line above the title

   The breadcrumbs belong to the shell and it prints them for every page that
   has them. Here they are the first line of the page, right under the header
   and right above a dark band, so they need the gap the shell does not give
   them: `padding: 18px 0 0` alone leaves the trail glued to the cover. */

.p-property .breadcrumbs { padding-bottom: 0.875rem; }

/* ---------------------------------------------------- 2. the status band

   A closed deal is information, so it is a line and not an alarm. The band is
   pale blue and the notice keeps the card ground: `.notice` fills itself with
   `--ground-2`, which on a paper band is the paper itself — invisible. */

.pstatus { padding-block: 1.25rem; }

.pstatus__in {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.875rem 1.5rem;
}

.pstatus__text {
    flex: 1 1 20rem;
    margin: 0;
    background: var(--card);
}

/* ---------------------------------------------------------- 3. the cover

   Full-bleed photograph, and the PRICE is on it as the headline: a price in a
   strip underneath reads as a caption, and this is the figure the whole page is
   about. The section carries the `hero` class, so the dark token set, the
   word-by-word headline and the figure strip all arrive from site.css. */

.pcover {
    min-height: min(84svh, 44rem);
    align-items: end;
    isolation: isolate;
}

.pcover__frame {
    position: absolute;
    inset: 0;
    z-index: -2;
}

.pcover__frame > * {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* At this size the placeholder's centred mark would land in the middle of the
   title and read as a stray box. The field alone is the right failure. */
.pcover__frame .ph::after { display: none; }

/* The one motion that runs without being triggered: slow enough that you only
   notice it if you stop to look. */
@media (prefers-reduced-motion: no-preference) {
    .pcover__frame > img { animation: pcover-drift 30s ease-in-out infinite alternate; }
}

@keyframes pcover-drift {
    from { transform: scale(1.03) translate3d(0, 0, 0); }
    to   { transform: scale(1.13) translate3d(-1.5%, -1.5%, 0); }
}

/* The scrim. Fixed values on purpose (§10): it sits on a photograph. */
.pcover::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: linear-gradient(
        to top,
        rgba(4, 12, 16, 0.95) 0%,
        rgba(4, 12, 16, 0.64) 46%,
        rgba(4, 12, 16, 0.26) 100%
    );
}

.pcover__in {
    position: relative;
    padding-block: clamp(2.25rem, 5vw, 3.5rem);
}

.pcover__where { margin: 0; }

.pcover h1 {
    font-size: clamp(2rem, 4.8vw, 3.6rem);
    max-width: 24ch;
    margin: 1.125rem 0 0;
}

.pcover__price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.5rem 1.25rem;
    margin: 1.125rem 0 0;
}

/*
    WHITE, and not `--price`.

    `--price` on a dark ground is `--blue-4` (#7fd0ea), and §9.2 of the design
    document says why that token exists: the mockup wrote the price in amber, amber
    is spent, and `--blue-4` is the substitute for «blue text on a dark ground».
    But the mockup used amber for `.sec--dark .card__p` — the SMALL price on a dark
    card — and for the big display price on a dark ground it used `.pbox__p`, which
    is `color: var(--w)`. This figure is the second case, not the first, and it was
    given the first one's colour by analogy with the wrong element.

    Measured on the seeded cover at 390, sampling the composited ground behind the
    figure (the photograph with the scrim over it, mean relative luminance 0.032):
    #7fd0ea reaches 7.4:1 and white reaches 12.8:1. So this was never a contrast
    failure — it passes AA and AAA — it was a RANK failure. At 390 the price is
    32 px and the headline above it is 30 px, so the price is already the largest
    thing on the cover; at 7.4:1 against 12.8:1 for the white headline and 16:1 for
    the white square-metre figures under it, the largest thing on the cover was
    also the fourth-brightest. Looking for it, I found the title first, then the
    figures, then the price. On the same page the panel prints this identical figure
    in white at 41.6 px, and the phone bar prints it in ink: the cover was the one
    place where the number the page exists for was the dimmest way it is written.

    Fixed white rather than a role token because it sits on a photograph, which is
    the exception §10 names and the reason `.pcover__ref` beside it is a literal
    rgba too.
*/
.pcover__figure {
    font-family: var(--d);
    font-size: clamp(2rem, 5.8vw, 3.25rem);
    line-height: 1;
    letter-spacing: -0.03em;
    color: var(--w);
    font-variant-numeric: tabular-nums;
}

/* Not a figure: the same rule site.css states with `.card__p--request`. */
.pcover__figure--request { font-size: clamp(1.375rem, 3vw, 2rem); }

.pcover__ref {
    font-family: var(--m);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.68);
}

/* ------ the stats row, and it is the point of this page

   Glyph, figure, mono label — the row immobiliare.it puts under the price, with
   our figures: type, rooms, interior, exterior, energy class. The figures count
   up, because site.js reads data-to and puts the written string back at the end,
   separators and units and all.

   THE TILES ARE DECLARED HERE, and the comment that stood in this place said
   they arrived from `.stats` and `.stat` in site.css. They do not. Those two
   classes were DELETED from site.css — the note is beside the ticker, «THE THREE
   COUNTING FIGURES ARE GONE» — and templates/public/property.html.twig is the
   only thing left in the project that writes them. What survived the deletion
   was `flex` on the strip and a tile's padding on a tile with no ground, and the
   result was measurable, not a matter of taste:

     * no ground, no hairline, no radius: five stats as loose text on a
       photograph, legible only where the picture happens to be dark;
     * the padding outlived the tile, so at 390 the first glyph sat at x = 33
       while the pill, the headline and the price all sat at x = 20 — the strip
       was 13 px out of the cover's own left grid line;
     * above 26.25rem, where §12's grid does not reach, `.pstat` was a plain
       block and the glyph, the figure and the label were three inline boxes in
       one text flow. At 768 that broke the label across two lines with the
       separator orphaned at the end of the first: «Interni ·» / «m²», and in
       German at 320 it made a three-line stat out of «Wohnfläche · m²»;
     * `.pstat b` inherited Inter at 78 % white, where the approved component set
       the display face at full white.

   So the strip gets its component back, taken from the approved mockup's own
   declarations (public/mockup/e.html, `.stats` / `.stat`): a 2 px hairline grid
   inside a radius, a glass tile per cell, the figure in the display face in
   white, the mono label under it. The one departure is `backdrop-filter`, which
   the mockup used and this project has measured and refused — the tile carries a
   stronger alpha instead, exactly as `.pill` does.

   Laid out with FLEX and not with the mockup's grid, for one reason: the number
   of figures is whatever the agency filled in — two on a plot of land, five on a
   villa — and in a grid the last row of an odd count leaves an empty cell with
   the photograph showing through it. Wrapped flex items grow into the room
   instead, so the strip is solid at every count and every width, with no
   breakpoint that has to know how much data there is. */

.pstats {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    margin-top: clamp(1.5rem, 4vw, 2.25rem);
    border-radius: 0.875rem;
    overflow: hidden;
    /* The seam between the tiles: what the 2 px gap shows through. */
    background: rgba(255, 255, 255, 0.14);
    /* And the edge of the panel. Without a backdrop-filter the photograph comes
       straight through the tiles, so over a bright crop the block has no outline
       of its own — the same problem `.pill` solves the same way. */
    border: 1px solid rgba(255, 255, 255, 0.18);
}

/*
    11.5rem, and the old value was 8.75rem. The basis is the only thing that
    decides how many tiles a row holds, and 8.75rem (140 px) put five of them on
    the 728 px band at 768: a tile spends 36 px of padding plus a 20 px glyph plus
    an 11 px gap before its text starts, so 144 px leaves 77, and «150 m²» set in
    26 px of Fraunces is 90 px. The FIGURE wrapped — «150» over «m²» — which does
    not read as a line break, it reads as a fault.

    184 px is the one value that satisfies all four of the widths this was checked
    at: two per row at 430 (2 x 184 + 2 = 370 in 390), three plus two at 768
    (4 x 184 + 6 = 742 does not fit 728), and all five in one row from 1024
    (5 x 184 + 8 = 928 in 936) through 1400. No figure wraps at any of them.

    What no basis can do is avoid a last tile alone on its row at EVERY width:
    five is five, and wherever the row holds four the fifth is by itself and grows
    to the whole band. With this value that band is a container of 742 to 927 px —
    roughly 830 to 1015 of viewport — and there the fifth tile is a full-width row
    of the same panel with its content on the panel's own left grid line, which is
    how every other band on this page is built. It is the least bad of the
    available shapes, not a shape nobody noticed.
*/
.pstat {
    flex: 1 1 11.5rem;
    min-width: 0;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 0.6875rem;
    align-items: center;
    padding: 0.9375rem 1.125rem;
    /* On a photograph, so fixed values (§10) and no backdrop-filter. */
    background: rgba(8, 22, 29, 0.55);
}

/* The glyph spans both rows and is centred on the pair, so it reads as the
   picture of the whole fact rather than as a mark between two lines. */
.pstat > svg {
    grid-row: 1 / 3;
    width: 1.25rem;
    height: 1.25rem;
    stroke: var(--blue-4);
    stroke-width: 1.6;
    fill: none;
}

.pstat b {
    font-family: var(--d);
    font-size: clamp(1.5rem, 3.4vw, 1.9rem);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--w);
    font-variant-numeric: tabular-nums;
}

/* A type name and an energy letter are words, not figures: at the figure size
   "Casa colonica" becomes the loudest thing on the photograph. */
.pstat--word b {
    font-size: clamp(1.125rem, 2.4vw, 1.375rem);
    letter-spacing: -0.01em;
}

.pstat span {
    display: block;
    margin-top: 0.375rem;
    font-size: 0.59375rem;
    letter-spacing: 0.14em;
    color: rgba(255, 255, 255, 0.58);
}

/* ------------------------------------------ 4. narrative and the panel */

.psheet .shead { margin-bottom: 1.75rem; }
.psheet__main { min-width: 0; }

/* Where it is, said once, at the foot of the narrative. The dossier states it
   as data; this is the line you read. */
.psheet__where {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin: 1.75rem 0 0;
    padding-top: 1.375rem;
    border-top: 1px solid var(--hair);
    font-family: var(--m);
    font-size: 0.71875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-3);
}

.psheet__where svg {
    width: 1.0625rem;
    height: 1.0625rem;
    stroke: var(--accent);
    stroke-width: 1.6;
    fill: none;
    flex: 0 0 auto;
}

/* ------ the contact box

   `.pbox__q` is three columns in site.css because the mockup had three
   figures. Here it has one, two or three depending on what the agency filled
   in, so the flow decides the count: an empty fourth cell would show as a
   hairline stub. */

.pbox__q {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
}

.pbox__p--request { font-size: 1.5rem; }
.bar__p--request { font-size: 1.05rem; }

.pbox__a { gap: 0.625rem; }

.pbox .cta { text-align: left; }
.pbox .cta svg { flex: 0 0 auto; }

.pbox__note {
    display: flex;
    gap: 0.625rem;
    margin: 0.375rem 0 0;
    font-size: 0.78125rem;
    line-height: 1.5;
    color: var(--text-3);
}

.pbox__note svg {
    width: 1rem;
    height: 1rem;
    margin-top: 0.125rem;
    stroke: currentColor;
    stroke-width: 1.6;
    fill: none;
    flex: 0 0 auto;
}

/* -------------------------------------------------- 5. the data sheet

   `.specs` and `.sp` do the work. What is added: room to breathe, and the
   energy class as a designed mark — the letter in a filled chip with the
   seven-segment scale under it, so "C" says where C falls. */

.dossier .sp {
    padding: 1.25rem 1.375rem;
    gap: 1rem;
}

.dossier__value { margin: 0.3125rem 0 0; }

.eclass {
    display: inline-block;
    min-width: 2.375rem;
    padding: 0.1875rem 0.625rem;
    border-radius: 0.4375rem;
    background: var(--fill);
    color: var(--fill-text);
    font-size: 0.9375rem;
    letter-spacing: 0.04em;
    text-align: center;
}

.dossier .ebar { max-width: 11rem; }

/* Nine rows in two columns leave a tenth cell empty, and an empty cell in a
   grid whose gaps ARE the hairline is a grey stub with a rounded corner. The
   last row takes the whole width when the count is odd. */
.dossier .sp:last-child:nth-child(odd) { grid-column: 1 / -1; }

/* ---------------------------------------------------- 6. the gallery

   One large photograph, the others in a strip under it, a counter, and a
   control that opens the lot. The stage is capped in height rather than left to
   its ratio: 16/10 across a 1300px band is 800px tall, which is a photograph
   nobody has scrolled past yet. */

.pviewer { background: var(--ph-a); }

.pviewer__stage {
    display: block;
    position: relative;
}

.pviewer__stage > .image,
.pviewer__stage > .ph {
    width: 100%;
    aspect-ratio: 16 / 10;
    max-height: min(70svh, 38rem);
    object-fit: cover;
}

.pviewer__stage:focus-visible { outline-offset: -0.25rem; }

/* On a 320 px stage the counter and the "see all" control are 30 px wider than
   the photograph between them, so the counter goes to the other corner. */
@media (max-width: 29.9375rem) {
    .pviewer .vcount { top: 1rem; bottom: auto; }
}

/* `.vfull` is a link in site.css and a button here: it opens the viewer, and a
   control that does nothing without JavaScript ships hidden (docs/DESIGN.md
   §13), which a link to a file cannot do. */
.vfull {
    border: 0;
    cursor: pointer;
    font-family: var(--t);
}

/* The strip scrolls sideways instead of wrapping into a second and third row:
   a listing with twenty photographs would otherwise push the enquiry form off
   the second screen. */
.pthumbs {
    display: flex;
    grid-template-columns: none;
    gap: 0.5625rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    padding-bottom: 0.25rem;
    scrollbar-width: thin;
}

.pthumbs__item { flex: 0 0 clamp(4.5rem, 13vw, 7rem); }
.pthumbs a { display: block; }

/* --------------------------------------------------------- 7. the video */

/* 34rem and not more: the largest poster YouTube serves for every video is
   hqdefault at 480 px, and past this width it is visibly upscaled. */
.pvideo {
    margin-top: clamp(2rem, 5vw, 3rem);
    max-width: 34rem;
}

.pvideo__title {
    margin-bottom: 0.875rem;
    font-size: 1.15rem;
}

.pvideo__stage {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-l);
    overflow: hidden;
    background: var(--night);
}

.pvideo__poster {
    position: absolute;
    inset: 0;
    display: block;
    text-decoration: none;
}

.pvideo__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.74;
    transition: opacity 0.4s var(--e), transform 0.8s var(--e);
}

.pvideo__poster:hover .pvideo__image { opacity: 0.9; transform: scale(1.03); }

/* On a photograph: fixed white, dark mark (§10). */
.pvideo__play {
    position: absolute;
    left: 1.125rem;
    bottom: 1.125rem;
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.6875rem 1.125rem;
    border-radius: 99px;
    background: rgba(255, 255, 255, 0.94);
    color: var(--night);
    font-size: 0.84375rem;
    font-weight: 600;
}

.pvideo__play svg {
    width: 0.9375rem;
    height: 0.9375rem;
    fill: currentColor;
    stroke: none;
}

.pvideo__frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

/* ------------------------------------------------------ 8. the enquiry

   The form partial brings its own pill, heading and introduction: this band
   gives it a ground, a number and a measure. */

.penquiry__in { max-width: 46rem; }
/* Same measure as the card, or the number stops lining up with it. */
.penquiry .snum { max-width: 46rem; margin-bottom: 1.125rem; }
.penquiry .form__title { font-size: clamp(1.7rem, 3.6vw, 2.6rem); }

/* ---------------------------------------------------- 9. the territory

   The card is the shared partial and it is built out of the global card
   vocabulary, so all this owes it is the title line and one ratio: three
   photographs of different heights in a row of three is the fault the frame
   exists to prevent. */

.pexp__item { min-width: 0; }

/*
    The anchor IS the card, so everything inside it is a <span> — and a span with
    padding, a ratio or a margin is still an inline box, which lays none of them
    out. Making the three of them blocks is what the partial means by "the page
    gives it its title line": without it the caption sits on the card's own edge.
*/
.pexp .card__ph,
.pexp .card__b,
.pexp .card__t,
.pexp .experience-card__title { display: block; }

.pexp .card__ph { aspect-ratio: 3 / 2; }

.pexp .card__ph > .image,
.pexp .card__ph > .ph {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.pexp .experience-card__title {
    display: block;
    margin-top: 0.5625rem;
    font-family: var(--d);
    font-size: 1.1875rem;
    line-height: 1.3;
    letter-spacing: -0.02em;
    color: var(--heading);
}

/* --------------------------------------------------- 10. the viewer

   A native <dialog>: showModal() traps the focus and closes on Escape without a
   line of ours. Chrome on a photograph, so fixed white with a dark mark (§10),
   and the counter bottom left because nothing on this site is centred. */

.lightbox {
    position: fixed;
    inset: 0;
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
    padding: 0;
    border: 0;
    background: rgba(4, 12, 16, 0.97);
}

.lightbox::backdrop { background: rgba(4, 12, 16, 0.9); }

.lightbox__photo {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.lightbox__counter {
    position: absolute;
    left: 1rem;
    bottom: 1rem;
    margin: 0;
    padding: 0.5rem 0.9375rem;
    border-radius: 99px;
    background: rgba(8, 22, 29, 0.8);
    backdrop-filter: blur(8px);
    color: #fff;
    font-family: var(--m);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
}

.lightbox__nav,
.lightbox__close {
    position: absolute;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(8px);
    cursor: pointer;
    transition: transform 0.24s var(--e), background 0.24s;
}

.lightbox__nav svg,
.lightbox__close svg {
    stroke: var(--night);
    stroke-width: 2;
    fill: none;
}

.lightbox__nav {
    top: 50%;
    width: 3rem;
    height: 3rem;
    transform: translateY(-50%);
}

.lightbox__nav svg { width: 1.375rem; height: 1.375rem; }
.lightbox__nav:hover { background: #fff; transform: translateY(-50%) scale(1.08); }
.lightbox__nav--previous { left: 0.875rem; }
.lightbox__nav--next { right: 0.875rem; }

.lightbox__close {
    top: 0.875rem;
    right: 0.875rem;
    width: 2.75rem;
    height: 2.75rem;
}

.lightbox__close svg { width: 1.25rem; height: 1.25rem; }
.lightbox__close:hover { background: #fff; transform: scale(1.08); }

/* ------------------------------------------------------ 11. the phone bar */

/* The bar is site.css furniture; it only needs its two lines to sit tight. */
.bar__r + .bar__p { margin-top: 0.125rem; }

@media (min-width: 40.625rem) {
    .pthumbs__item { flex-basis: 7rem; }
}

/* ==========================================================================
   The refinement pass.

   The owner's judgement of the sheet was "tutto troppo grossolano" — everything
   too coarse. It is a fair reading of what happens when a page is assembled from
   correct parts without a second pass over the intervals: the sizes step in even
   jumps, the mono labels sit at the same tracking as the values they label, and
   the rules are all one weight. Refinement is mostly a matter of unequal
   intervals and one weight less everywhere.

   Nothing here changes the structure. It is the second pass.
   ========================================================================== */

/* --- 1. one step down at the top, and a tighter fit ---------------------- */

/* Display type at 3.6rem over a photograph reads as a poster. The sheet is a
   document about a house: the title has to be the largest thing without being
   the loudest. */
.property-cover__title,
.pcover__title {
    font-size: clamp(1.875rem, 4.2vw, 3.125rem);
    letter-spacing: -0.032em;
    line-height: 1.06;
}

/* The price keeps its rank — still the second-largest thing — but the gap
   between it and the title closes: two figures a whole step apart look like two
   unrelated decisions. */
.property-cover__price,
.pcover__price {
    font-size: clamp(1.625rem, 3.4vw, 2.5rem);
    letter-spacing: -0.028em;
}

/* --- 2. mono labels stop competing with their values -------------------- */

/* Every small-caps label on the page: one notch smaller, wider tracked, and a
   tone quieter. A label set at the same weight as its value makes the reader do
   the sorting; this is what "grossolano" actually looks like up close. */
.dossier__label,
.pspec__label,
.psheet__label,
.property-cover__reference,
.pcover__reference,
.pstats__label,
.pquick__label {
    font-size: 0.59375rem;
    letter-spacing: 0.17em;
    font-weight: 400;
    color: var(--text-3);
}

/* --- 3. unequal rules ---------------------------------------------------- */

/* A page where every rule is 1px of the same colour reads flat. The rule that
   closes a block is full strength; the ones that separate rows inside it are
   half. The eye reads the group before it reads the rows. */
.dossier__row,
.pspec__row,
.psheet__row {
    border-bottom-color: color-mix(in srgb, var(--hair) 55%, transparent);
}

.dossier__row:last-child,
.pspec__row:last-child,
.psheet__row:last-child {
    border-bottom-color: var(--hair);
}

/* --- 4. the numbers line up ---------------------------------------------- */

/* Tabular figures everywhere a figure appears, not only in the data sheet: a
   price, a surface and a room count that shift by a pixel between rows is the
   detail nobody names and everybody feels. */
.dossier__value,
.pspec__value,
.psheet__value,
.pquick__value,
.pstats__value,
.pbox__price,
.property-cover__price,
.pcover__price {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
}

/* --- 5. the intervals ---------------------------------------------------- */

/* Vertical rhythm inside the sheet, tightened by roughly a fifth. The bands keep
   their generous outer spacing — that is what makes them read as bands — but a
   data sheet with 1rem of air in every row looks unfinished rather than airy. */
.dossier__row,
.pspec__row,
.psheet__row {
    padding-block: 0.78125rem;
}

/* --- 6. the seams ------------------------------------------------------- */

/* The scrim over the opening photograph gets one more stop. Two stops make a
   visible edge on a photograph with a horizon in it — which is every photograph
   on this coast. */
.property-cover__veil,
.pcover__veil {
    background: linear-gradient(
        to top,
        rgba(4, 12, 16, 0.94) 0%,
        rgba(4, 12, 16, 0.80) 22%,
        rgba(4, 12, 16, 0.52) 46%,
        rgba(4, 12, 16, 0.22) 72%,
        rgba(4, 12, 16, 0) 100%
    );
}

/* Photographs get a hairline inside their own radius. Without it a light image
   on a light ground has no edge at all, and the card looks like it is missing
   something. */
.property-card__frame,
.pgallery__link,
.pthumbs a,
.pviewer {
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 8%, transparent);
}

/* ==========================================================================
   The enquiry form, given the treatment it deserves.

   This is where the money arrives, and it was the plainest block on the page: a
   heading, a stack of borderless fields and a button, all on a flat band. On a
   listing at €1.250.000 that reads as an afterthought.

   It becomes a CARD lifted off the band, so the form is visibly a thing you act
   on rather than more page. Everything else here is the same second pass the rest
   of the sheet got: unequal intervals, one weight less on the labels, and fields
   that show where the cursor is.
   ========================================================================== */

.penquiry__in {
    max-width: 44rem;
    /* Centred, on the owner's instruction. It matters more here than it would
       elsewhere: this band is the end of the page and the card is the only thing on
       it, so a 44rem card pinned to the left of a 1400rem container reads as a
       column that lost its neighbour. Everything else on the page stays
       left-aligned — this is the one block that is alone on its ground. */
    margin-inline: auto;
    background: var(--card);
    border-radius: var(--radius-l);
    box-shadow: var(--sh-2);
    padding: clamp(1.5rem, 4vw, 2.75rem);
}

/* The section number sits OUTSIDE the card, on the band: it belongs to the page's
   sequence, not to the form. It gets the card's measure and the same auto margins
   so it lines up with the card's left edge — a number left at the page edge above a
   centred card looks like two unrelated things. The number itself stays
   left-aligned inside that measure: the numbered headers are a system
   (docs/DESIGN.md §5) and centring the text would break it. */
.penquiry .snum {
    display: block;
    max-width: 44rem;
    margin-inline: auto;
    margin-bottom: 1rem;
}

.penquiry__in > .snum { display: none; }

.penquiry .form__title {
    font-size: clamp(1.5rem, 3vw, 2.125rem);
    letter-spacing: -0.028em;
    line-height: 1.1;
    max-width: 24ch;
}

.penquiry .lead {
    max-width: 42ch;
    margin: 0.75rem 0 0;
    font-size: 1rem;
    color: var(--text-2);
}

/* The reference pill leads, above the heading: the first thing to know is that
   the agency will already know which house you mean. */
.penquiry .prefill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1.125rem;
    padding: 0.4375rem 0.875rem;
    border-radius: 99px;
    background: color-mix(in srgb, var(--blue) 12%, transparent);
    color: var(--blue-3);
    font-family: var(--m);
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* --- the fields ---------------------------------------------------------- */

.penquiry .form {
    display: grid;
    gap: 1.125rem;
    margin-top: clamp(1.5rem, 3vw, 2rem);
}

@media (min-width: 40rem) {
    .penquiry .form { grid-template-columns: 1fr 1fr; }
    .penquiry .form__wide { grid-column: 1 / -1; }
}

.penquiry .form__label {
    display: block;
    margin-bottom: 0.4375rem;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--text);
}

.penquiry .form__required { color: var(--blue-3); }

/* Nessun raggio: quello dei campi lo porta site.css §27.9, per tutto il sito. */
.penquiry .form__field {
    width: 100%;
    padding: 0.8125rem 0.9375rem;
    border: 1.5px solid var(--hair);
    background: var(--ground);
    font-family: var(--t);
    font-size: 1rem;
    color: var(--text);
    /* NON `var(--transition)`: quel token lo dichiara solo admin.css, e un valore
       non valido porta via l'INTERA dichiarazione — i campi della richiesta erano
       gli unici comandi del sito a cambiare stato di scatto mentre tutto intorno
       a loro andava in dissolvenza. docs/DESIGN.md §18.4 dava questo difetto per
       chiuso e ne era rimasta una riga. */
    transition: border-color .18s var(--e), box-shadow .18s var(--e), background .18s var(--e);
}

.penquiry .form__field:hover { border-color: var(--line-2); }

/* A ring, not a colour change: the ring says WHERE the cursor is from across the
   room, which is the only thing a focus state has to do. */
.penquiry .form__field:focus {
    outline: none;
    border-color: var(--blue);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 16%, transparent);
}

.penquiry textarea.form__field { min-height: 7rem; resize: vertical; }

.penquiry .form__field--invalid,
.penquiry .form__field[aria-invalid='true'] {
    border-color: var(--blue-3);
    background: color-mix(in srgb, var(--blue-3) 4%, transparent);
}

.penquiry .form__hint {
    display: block;
    margin-top: 0.375rem;
    font-size: 0.75rem;
    color: var(--text-3);
}

.penquiry .form__error {
    display: block;
    margin: 0.375rem 0 0;
    font-size: 0.8125rem;
    font-weight: 550;
    color: var(--blue-3);
}

/* --- consent ------------------------------------------------------------- */

/* Legible, not buried. It is a legal consent and the person giving it has a right
   to read it without leaning in. */
.penquiry .form__consent {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.9375rem 1rem;
    border-radius: var(--radius);
    background: var(--ground-2);
    font-size: 0.84375rem;
    line-height: 1.55;
    color: var(--text-2);
    cursor: pointer;
}

.penquiry .form__consent input {
    flex: 0 0 auto;
    width: 1.125rem;
    height: 1.125rem;
    margin-top: 0.125rem;
    accent-color: var(--blue);
}

.penquiry .form__consent a { color: var(--blue-3); }

/* --- the decision -------------------------------------------------------- */

.penquiry .form__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-top: 0.375rem;
}

/* Full width on a phone: a button you reach with a thumb, not one you aim at. */
@media (max-width: 39.99rem) {
    .penquiry .form__actions .cta { width: 100%; justify-content: center; }
}

.penquiry .form__errors {
    margin-bottom: 1.25rem;
    padding: 1rem 1.125rem;
    border-left: 3px solid var(--blue-3);
    border-radius: var(--radius-s);
    background: color-mix(in srgb, var(--blue-3) 5%, transparent);
    font-size: 0.875rem;
}

.penquiry .form__errors-title { font-weight: 600; margin: 0 0 0.375rem; }

/* The honeypot stays off-screen rather than display:none — some bots skip hidden
   fields but fill positioned ones, and a screen reader still gets the label. */
.penquiry .form__trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ==========================================================================
   Share.

   On this coast a listing travels on WhatsApp, so the control is next to the
   price rather than buried at the foot of the page. On a phone it is one button
   that opens the native sheet; on a desktop it is a fold with WhatsApp, e-mail
   and copy-the-link. Never both — site.js removes the one it is not using.

   It sits over the photograph, so it is glass on dark rather than a filled
   button: a solid control there would compete with the price.
   ========================================================================== */

.pshare,
.pshare__native {
    position: relative;
    display: inline-block;
    margin-top: 1.125rem;
}

.pshare__button,
.pshare__native {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5625rem 0.9375rem;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: 99px;
    /* A dark floor under the white veil instead of `backdrop-filter: blur(10px)`
       — the same swap, and for the same measured reason, as `.pill` in site.css.
       These two controls sit inside `.pcover`, on the cover photograph, and that
       photograph drifts for as long as the page is open (`pcover-drift`), so
       each blur was re-rendered on every frame. This cover carried eight of them
       at once: the pill, these two, and five `.stat` tiles. Dropping all eight
       took the page from 3.65 to 2.09 ms of CPU per frame, the GPU process's
       share from 2.47 to 0.78 — measured on an M4 at 1440x900 dpr2. */
    background-color: rgba(8, 22, 29, 0.48);
    background-image: linear-gradient(rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1));
    color: #fff;
    font-family: var(--m);
    font-size: 0.6875rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    cursor: pointer;
    list-style: none;
    /* Not `var(--transition)`: nothing on the public site declares it, so this
       declaration was invalid and the share control changed state instantly.
       §16 of this file already caught the same token on another rule. */
    transition: background .2s var(--e), border-color .2s var(--e), transform .2s var(--e);
}

.pshare__button::-webkit-details-marker { display: none; }
.pshare__button::marker { content: ''; }

/* `background-image`, not the `background` shorthand: the shorthand would wipe
   out the dark floor declared above and leave a light veil alone on a
   photograph. Only the veil brightens on hover. */
.pshare__button:hover,
.pshare__native:hover {
    background-image: linear-gradient(rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2));
    border-color: rgba(255, 255, 255, 0.5);
    transform: translateY(-1px);
}

.pshare__button:focus-visible,
.pshare__native:focus-visible {
    outline: 3px solid var(--blue-4);
    outline-offset: 3px;
}

.pshare__icon {
    width: 0.9375rem;
    height: 0.9375rem;
    stroke: currentColor;
    stroke-width: 1.7;
    fill: none;
    flex: 0 0 auto;
}

/* The panel opens upward on the cover: downward it would fall off the band and
   be clipped by the section's overflow. */
.pshare__panel {
    position: absolute;
    left: 0;
    bottom: calc(100% + 0.5rem);
    z-index: 20;
    min-width: 13rem;
    padding: 0.375rem;
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--sh-2);
    border: 1px solid var(--card-line);
}

.pshare__link {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    padding: 0.625rem 0.75rem;
    border: 0;
    border-radius: var(--radius-s);
    background: none;
    font-family: var(--t);
    font-size: 0.90625rem;
    font-weight: 500;
    color: var(--text);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
    transition: background .2s var(--e), color .2s var(--e);
}

.pshare__link:hover {
    background: color-mix(in srgb, var(--blue) 9%, transparent);
    color: var(--blue-3);
}

.pshare__link:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: -2px;
}

.pshare__glyph {
    width: 1.0625rem;
    height: 1.0625rem;
    stroke: currentColor;
    stroke-width: 1.6;
    fill: none;
    flex: 0 0 auto;
}

/* The confirmation is the label changing, not a toast: it happens where the
   finger already is. */
.pshare__link.is-copied {
    background: color-mix(in srgb, var(--blue) 14%, transparent);
    color: var(--blue-3);
}

@media (max-width: 39.99rem) {
    .pshare__panel { min-width: 11.5rem; }
}

/* The address as selectable text: the last resort when neither clipboard path
   works. It is monospaced and it breaks anywhere, because a URL that overflows
   its panel cannot be read to be copied by hand. */
.pshare__url {
    display: block;
    padding: 0.5rem 0.75rem 0.625rem;
    font-family: var(--m);
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--text-2);
    overflow-wrap: anywhere;
    user-select: all;
}

/* ==========================================================================
   The phone pass.

   Everything above was designed at 390 and it holds at 390. What it does not
   hold at is 320, and the faults are all of one kind: a block whose flex basis,
   padding or overlay was sized for a wider column and, 70 px narrower, becomes
   a tower or a smear over a photograph. Measured on the seeded database, at
   320/360/390/430/768/1024, `Emulation.setDeviceMetricsOverride` with
   `mobile: true` — a headless window clamps at about 500 px and then reports
   whatever you asked for, so no number here was taken from a window.

   The idiom is `max-width`, against the mobile-first preference, because this
   file already reaches for `max-width` five times and one file should speak one
   way. Nothing below 26.25rem exists to undo a desktop decision: the desktop
   values above ARE the design, and these are corrections to them at a width the
   design was not drawn at.
   ========================================================================== */

/* -------------------------------------------- 12. the cover stops being a tower

   `.pstat` asks for `flex: 1 1 8.75rem`, which is 140 px, and with the strip's
   2 px gap 140 + 2 + 140 = 282 where a 320 px phone offers 280. Two tiles missed
   each other BY TWO PIXELS, so all five stacked — `.pstats` measured 544 px tall
   and `.pcover` 889 px, which is a screen and a half of dark photograph before
   the first word of the listing.

   The basis becomes a percentage, so the count no longer depends on a rem guess:
   two per row at every width in the range, and each tile 60 px tall instead of
   105. The sideways layout the first version of this block declared here now
   lives in §3, where it belongs — it was never a phone correction, it was the
   component, and above this breakpoint the strip had none.

   What is left here is what really is width-specific: the basis, the intervals
   and one step down on the two figure sizes. */

@media (max-width: 26.25rem) {
    .pstats { margin-top: clamp(1.125rem, 3.5vw, 1.75rem); }

    .pstat {
        /* Half the strip, less half of its 2 px gap. */
        flex: 1 1 calc(50% - 1px);
        column-gap: 0.5625rem;
        padding: 0.6875rem 0.8125rem;
    }

    .pstat > svg { width: 1.0625rem; height: 1.0625rem; }

    .pstat b { font-size: 1.3125rem; }
    .pstat--word b { font-size: 0.9375rem; }
    .pstat span { margin-top: 0.0625rem; }
}

/* ------------------------------------------------ 13. the narrative reads

   Two faults at opposite ends of the range, one value.

   On a phone the opening paragraph is 19.5 px in a 280 px column: 29 characters
   a line, four words, nine lines for one paragraph. Under 30rem it steps down
   and the leading closes from 1.78 to 1.62 — at four words a line, 1.78 reads
   as a list of fragments rather than as a sentence.

   At 768 and 1024 the opposite: `.prose` caps at `66ch`, and `ch` in Inter is
   11.04 px, so the cap computes to 728.6 px and the description runs NINETY
   characters a line at 17.5 px. 66ch was meant to be 66 characters. 36rem is
   576 px, which is 71 characters at 17.5 px and 64 at 19.5 px — inside the
   45-75 band at both sizes, which `66ch` is at neither. */

.psheet .prose { max-width: 36rem; }

@media (max-width: 30rem) {
    .psheet .prose { font-size: 1rem; line-height: 1.62; }
    .psheet .prose p:first-child { font-size: 1.0625rem; }
}

/* ------------------------------------- 14. the price panel's facts, in German

   `.pbox__q` divides its width by the number of facts, three at 320 giving
   92.7 px a cell and 72.7 px inside `.q`'s padding. The Italian labels are
   VANI, INTERNI, ESTERNI and fit. The German ones are WOHNFLÄCHE and
   AUSSENFLÄCHE, and the second measured 76 px of scrollWidth in a 73 px box —
   clipped, silently, because `.pbox` carries `overflow: hidden`, so it never
   showed up as a document that scrolls sideways. It showed up as a word with
   its last letter shaved off.

   Narrower padding and tighter tracking buy 8 px; `overflow-wrap` is the
   guarantee for the language nobody has typed in yet — a broken word is ugly,
   a shaved one is a bug. */

@media (max-width: 26.25rem) {
    .pbox__q .q { padding-inline: 0.5rem; }

    .pbox__q .q span {
        letter-spacing: 0.06em;
        overflow-wrap: anywhere;
    }
}

/* ----------------------------------------- 15. the gallery gives the picture back

   Measured at 320: the stage is 280 x 175 and the chrome sitting on it —
   `.vnav` at 48 px square and `.vfull` 202 x 39 under it — covered from 64 px
   to 159 px, which is 54 % of the height of the photograph, in the middle of
   it. Three floating controls in the lower-left corner of a postcard.

   The stage takes a phone-shaped crop, which is 35 px more picture, and the
   "see all" control stops floating: it becomes a strip of its own along the foot
   of the frame, full width, centred, 46 px tall. The frame grows by exactly the
   height of the strip — `padding-bottom` on `.pviewer`, so `bottom: 0` lands in
   the padding and the strip takes nothing from the photograph, which is the
   whole point and the first version of this got it wrong by overlaying it.

   Out of the frame it is no longer a control on a photograph, so it stops being
   fixed white and reads the role tokens like everything else: `--card` with a
   hairline above it, which is what makes it look like the foot of the frame
   rather than a button that happens to be down there.

   Result at 320: 210 px of unobstructed picture where there were 175 with 95 px
   of chrome over the middle of them, the arrows the only thing left on it, and
   the "see all" control the LARGEST target on the band instead of the smallest.
   The counter is already top right below 30rem (§6). */

@media (max-width: 30rem) {
    .pviewer { padding-bottom: 2.875rem; }

    .pviewer__stage > .image,
    .pviewer__stage > .ph { aspect-ratio: 4 / 3; }

    .pviewer .vfull {
        left: 0;
        right: 0;
        bottom: 0;
        justify-content: center;
        min-height: 2.875rem;
        border-radius: 0;
        border-top: 1px solid var(--hair);
        background: var(--card);
        color: var(--text);
    }
}

/* --------------------------------------------- 16. forty-four pixels, everywhere

   Measured heights before this block, at every width from 320 to 1024, on the
   controls an estate agent's client actually taps: share 38.1, see-all 39.4,
   a share panel entry 43.9, the "all the experiences" arrow 19, the consent
   checkbox 18 x 18. The minimum is 44, and it is not a preference: it is the
   width of an adult fingertip.

   `min-height` and not `padding`, so nothing here changes a size that is
   already correct on a desktop. */

.pshare__button,
.pshare__native,
.pviewer .vfull {
    min-height: 2.75rem;
}

.pshare__link { min-height: 2.75rem; }

/* The arrow is a mono line 19 px tall in a header row. It keeps its type and
   gains a box: the target grows, the line does not move. */
.psheet .arrow,
.pmedia .arrow,
.pexp .arrow {
    min-height: 2.75rem;
    align-items: center;
}

.penquiry .form__consent input {
    width: 1.375rem;
    height: 1.375rem;
    margin-top: 0;
}

/* The panel can never be taller than the room above the button, and never wider
   than the phone: it opens upward (§Share) and upward there is a fixed header. */
.pshare__panel {
    max-width: calc(100vw - 2.5rem);
    max-height: calc(100svh - var(--top-h) - 8rem);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ------------------------------------------------- 17. the enquiry card at 320

   The card's padding floor is 1.5rem, and with the 20 px page gutter that is
   88 px of chrome on a 320 px screen — 27 % of the width, spent on air, so the
   consent sentence came out 25 characters a line over SEVEN lines. Below
   22.5rem the floor comes down to 1.125rem and the consent's own inset padding
   with it, which hands 46 px back to the text: five lines of 31 characters.

   The consent also goes up half a step in size. It is the one paragraph on the
   page with legal effect and it was the smallest type in the card. */

@media (max-width: 22.5rem) {
    .penquiry__in { padding: 1.125rem; }
    .penquiry .form { gap: 1rem; }
    .penquiry .form__consent {
        padding: 0.8125rem 0.75rem;
        gap: 0.625rem;
    }
}

.penquiry .form__consent { font-size: 0.875rem; }

/* --------------------------------------- 18. the field you can see, and the error

   Two defects docs/DESIGN.md names and this file still carried.

   §9.3: the field border was `--hair` (#dde5e9), which measures 1.28:1 on the
   card. That is not a visible control — on the pale-blue ground of this band the
   fields read as four blue smudges — and `--line-2` (#7f939f) exists in
   site.css §1 for exactly this element.

   §15: five declarations in this file read `var(--deep-blue)`, a token only
   `admin.css` declares. Invalid at computed-value time, so all five were
   dropped, and because an invalid `border-left` shorthand takes the whole
   shorthand with it the error summary lost its rule AND its wash and became
   plain text on the card. On a phone that is the difference between an operator
   seeing why the form came back and giving up on it. `--blue-3` is the declared
   token for blue as text on a light ground, which keeps the file's own decision
   that a refused field is stated in blue and not in red.

   AGGIORNAMENTO: le cinque dichiarazioni di partenza sono state riparate sul
   posto — leggono `--blue-3` anche loro — quindi questo blocco non è più ciò che
   tiene in piedi lo stato di errore: è un doppione innocuo. Resta perché è dove
   il difetto è documentato, e perché toglierlo significherebbe fidarsi di sei
   righe sparse duecento righe più su. Quello che cambia è che il file adesso non
   nomina più nessun token che nessuno dichiara, e la verifica che lo controlla
   (docs/DESIGN.md §19.5) torna a passare a zero segnalazioni. */

.penquiry .form__field { border-color: var(--line-2); }

.penquiry .form__field--invalid,
.penquiry .form__field[aria-invalid='true'] {
    border-color: var(--blue-3);
    border-width: 2px;
    background: color-mix(in srgb, var(--blue-3) 5%, transparent);
}

.penquiry .form__error { color: var(--blue-3); }

.penquiry .form__errors {
    border-left: 3px solid var(--blue-3);
    background: color-mix(in srgb, var(--blue-3) 6%, transparent);
}

/* -------------------------------------------------- 19. the lightbox on a phone

   At 320 x 568 the dialog shows a landscape photograph as a 320 x 213 band in
   the middle of the screen, and the two 48 px arrows sat at 50 % — dead centre
   of the picture, 96 px of the 320 across it. There is a whole black screen
   above and below and the controls were standing on the only part of it that
   has anything to look at.

   They move to the bottom right, beside the counter that is already bottom
   left: one row of chrome, and the photograph is untouched. */

@media (max-width: 30rem) {
    .lightbox__nav {
        top: auto;
        bottom: 1rem;
        transform: none;
    }

    .lightbox__nav:hover { transform: scale(1.08); }
    .lightbox__nav--previous { left: auto; right: 4.25rem; }
    .lightbox__nav--next { right: 1rem; }
}

/* ==========================================================================
   The looking pass.

   Everything above was measured. This block is what came out of SEEING the page
   at 320, 390, 768 and 1400, in Italian and in German, with the reveal animations
   settled and every photograph decoded — screenshots read one band at a time
   rather than a whole page thumbnailed down to nothing.

   The measured passes had already made the sheet correct: nothing overflows and
   nothing is under 44 px. What they could not see is that a correct page can
   still spend a fifth of a phone screen on nine facts, fill a form's fields with
   the colour of the band behind the card, and park two white discs in the middle
   of the only photograph on the band. Those are the three faults here, plus two
   shapes that only go wrong when a label wraps.

   Order: the data sheet, the pills that wrap, the photograph the arrows were
   standing on, the enquiry card.
   ========================================================================== */

/* ------------------------------------------- 20. the data sheet, read closely

   Measured at 320 and at 390: nine rows, every one of them 85 px tall, 793 px of
   scrolling for nine facts — the longest single block on the page and the one the
   owner named as the reference («prendi come riferimento le schede di
   immobiliare»). Where the height goes: 40 px of vertical padding, a 13 px mono
   label, and the value on the line under it.

   And where the WIDTH goes is worse. The gutter before the label is 22 px of
   padding + a 20 px glyph + a 16 px gap = 58 px, on a card 280 px wide: 21 % of
   the sheet is an empty corridor down its left edge, and the glyph inside it is
   centred on a two-line stack, so it sits in the gap BETWEEN the label and the
   value and points at neither.

   Three changes, no restructuring: the intervals come in, the gutter comes in,
   and the stack tightens enough that "centred on the pair" lands on the value's
   own line instead of between the two. A row goes from 85 px to about 64 and the
   text column gains 12 px. Nine rows: 793 px to roughly 600 — two thirds of a
   phone screen handed back, with nothing removed and nothing made smaller to
   read.

   The label keeps its size deliberately. It is already 9.5 px; the room comes
   from the air around it, which is where it should come from. */

@media (max-width: 26.25rem) {
    .dossier .sp {
        padding: 0.875rem 1rem;
        gap: 0.75rem;
    }

    .dossier .dossier__value { margin-top: 0.0625rem; }

    /* The scale under the energy letter loses the interval it needed when the
       row was 85 px tall. */
    .dossier .ebar { margin-top: 0.375rem; }
}

/* ------------------------------------------------ 21. a pill is not a lozenge

   `.pill` and `.prefill` are both fully rounded — `border-radius: 99px` — and
   that is right for the thing they were drawn as: one line of mono, ends capped
   by half its height.

   At 320 neither of them is one line. The cover's pill carries the category and
   the locality («VENDITA · QUERCIANELLA, VALLE DEL CHIOMA», and in German
   «VERKAUF · …»), which measured 54 px tall over two lines; the enquiry card's
   prefill carries «RIFERIMENTO RIF-112 GIÀ COMPILATO» and measured 50 px over
   two. A two-line box with 27 px caps is not a pill any more, it is a speech
   balloon, and it is the first shape on the cover and the first shape in the
   form.

   So below the width where they stop fitting on one line, the ends stop being
   caps. Same colour, same border, same padding: a tag instead of a lozenge. */

@media (max-width: 26.25rem) {
    .pcover__where,
    .penquiry .prefill { border-radius: var(--radius); }
}

/* ------------------------------- 22. the arrows come off the photograph

   §19 moved the LIGHTBOX's arrows out of the middle of the picture at this same
   breakpoint, for this same reason, and stopped there. The in-page viewer kept
   its pair, and it is the worse of the two cases: measured at 320 the stage is
   280 x 210 and each `.vnav` is 48 px of `rgba(255,255,255,.92)` — near-opaque —
   at `top: 50%`. That is 96 px of white disc across 280 px of photograph, 34 % of
   its width, dead centre, on the only photograph the gallery band shows.

   §15's own note says «the arrows the only thing left on it» about the state it
   left the band in. This finishes that sentence. They go to the bottom right
   corner of the stage, above the foot strip §15 put along the bottom and
   diagonally opposite the counter §6 put top right: one corner of chrome, and the
   middle of the picture — where the house is — is untouched.

   44 px and not 48: the floor §16 set, and 8 px narrower means the pair spans
   96 px instead of 108 at the one width where that is the difference between
   sitting in the corner and sitting across the frame. */

@media (max-width: 30rem) {
    .pviewer .vnav {
        top: auto;
        bottom: 3.375rem;
        width: 2.75rem;
        height: 2.75rem;
        transform: none;
    }

    .pviewer .vnav:hover { transform: scale(1.08); }
    .pviewer .vnav--l { left: auto; right: 4.125rem; }
    .pviewer .vnav--r { right: 1rem; }

    /* Five photographs need 396 px of strip in a 280 px box, so it scrolls — and
       the fifth thumbnail was cut in half by the container's edge with nothing to
       say it could be dragged. Snapping is what says it. */
    .pthumbs { scroll-snap-type: x proximity; }
    .pthumbs__item { scroll-snap-align: start; }
}

/* -------------------------- 23. a form worth filling in for half a million

   §18 fixed half of one fault here and this is the other half. It changed the
   field's border from `--hair` to `--line-2`, because `--hair` at 1.28:1 is not a
   visible control. The field's FILL it left as `background: var(--ground)`, and
   `--ground` is by definition the colour of the band the card is lying on: on
   `.sec--blue` it is `--blue-l`. Sampled at 320, the field and the band measure
   the same rgb(230, 243, 248) — not similar, identical. So five fields and a
   186 px textarea read as holes punched through a white card to the page behind
   it, and the largest single area of colour in the whole card is the empty
   message box.

   `--card` is the role for a surface inside a card, it is what site.css's own
   `.form__field` uses, and with §18's `--line-2` border a white field on a white
   card is a drawn control rather than a gap. Nothing else about the field
   changes — the focus ring, the hover, the invalid state are all still §18's.

   The consent checkbox is the second thing here, and it was the one control on
   the page that was not designed: 22 px of browser default beside eight lines of
   German legal text. `appearance: none` and it becomes the same object as
   everything else in the card — `--line-2` on `--card`, the system radius, and
   `--fill` with a hand-drawn tick when it is checked. The tick is a data URI, not
   a pseudo-element: `::before` on an input is a browser-by-browser bargain, and
   `img-src 'self' data:` is already in the public CSP (app/Http/Headers.php).

   The size stays at §16's 1.375rem and the whole label stays the tap target, so
   nothing measured moves. */

.penquiry .form__field { background: var(--card); }

.penquiry .form__consent input {
    appearance: none;
    border: 1.5px solid var(--line-2);
    border-radius: var(--radius-s);
    background: var(--card);
    background-repeat: no-repeat;
    background-position: center;
    background-size: 0.875rem;
    cursor: pointer;
    /* NOT `var(--transition)`. Nothing declares that token — site.css §1 has
       `--e` for the easing and no duration token at all — so the five
       declarations in this file that reach for it are invalid at computed-value
       time and were dropped, silently, along with the one in site.css. Written
       the way the rest of the project writes it: a duration and `--e`. */
    transition: background-color 0.2s var(--e), border-color 0.2s var(--e);
}

.penquiry .form__consent input:checked {
    border-color: var(--fill);
    background-color: var(--fill);
    /* A tick, stroked like every other glyph on the page: 1.6 of white on blue. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l5 5 9-11'/%3E%3C/svg%3E");
}

.penquiry .form__consent input:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* The message box is six rows because six rows is right on a laptop. At 320 that
   is 186 px — a quarter of the screen — and it made the emptiest thing in the
   card the biggest. Four rows is still four sentences. */
@media (max-width: 26.25rem) {
    .penquiry textarea.form__field { height: 9rem; }
}

/* ------------------------------------- 24. the share sheet is the width of a phone

   §16 gave this panel a `max-width` so it could not be wider than the screen. Its
   `min-width` is still 13rem, and 13rem is what it takes: measured at 320 it opens
   184 px wide in a 320 px viewport, pinned to the left gutter, with «Copia il
   collegamento» broken over two lines and the plain-text address — the fallback
   site.js reveals when no clipboard path exists — over four.

   A share sheet on a phone is the width of the column it belongs to. The min and
   the max meet at the same value below 26.25rem, so the panel is exactly the
   content column: one line per entry, and the address over two lines instead of
   four. Nothing about where it opens changes — upward, because downward the
   band's own overflow clips it. */

@media (max-width: 26.25rem) {
    .pshare__panel { min-width: calc(100vw - 2.5rem); }
}

/* ==========================================================================
   §12. THE REFINEMENT PASS — the property sheet, brought up to site.css §24

   This is the page the whole site exists to reach, and it is the longest: a
   cover, a figure strip, a narrative, a price panel, a data sheet, a gallery, an
   enquiry form and a band of experiences. Six of those eight are declared in this
   file under names of their own, so the shared pass in site.css §24 reaches only
   part of the page.

   Nothing measured is touched. The cover's scrim, the price being white rather
   than `--blue-4`, the 11.5rem flex basis of a stat tile and the painting order
   that put the scrim back above the photograph are all recorded above with the
   numbers that produced them, and every one of them stands. What is added is the
   same four things §24 adds everywhere: an edge, a light source, a framed
   photograph and type set for its size.
   ========================================================================== */

/* ---- the cover ---------------------------------------------------------- */

/* Fraunces at 3.6rem asks for the display end of its optical axis, and the
   shadow is the same one the home's headline gets: it can only ever darken what
   is behind a glyph, so the contrast the scrim was measured for is a floor it
   raises rather than one it lowers. */
.pcover h1 {
    letter-spacing: -0.035em;
    font-variation-settings: 'opsz' 144;
    text-shadow: 0 1px 2px rgba(4, 12, 16, .26), 0 2px 40px rgba(4, 12, 16, .32);
}

.pcover__figure {
    font-variation-settings: 'opsz' 144;
    letter-spacing: -0.035em;
    text-shadow: 0 1px 2px rgba(4, 12, 16, .3), 0 2px 36px rgba(4, 12, 16, .36);
}

/* The strip of figures. It is a glass panel over a photograph with a 2px seam
   showing through between the tiles, and it worked; it simply had no light on
   it. The sheen along the top inside edge and a shadow under the whole panel are
   what separate it from the picture instead of laying it on top. */
.pstats {
    border-radius: 1rem;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .2), 0 12px 34px -14px rgba(4, 12, 16, .7);
}

/*
    THE TILE GOES DARKER, AND ITS LABEL GOES BRIGHTER. Measured, not preferred.

    The strip is glass over an unknown photograph, so the worst ground it can be
    asked to carry is a blown-out white pixel. Composited in sRGB, `--night` at
    .55 over white lands on a relative luminance of 0.231, and against that:

      the figure   white, 24–30px display  →  4.55:1   passes (large text: 3:1)
      the label    white .58, 9.5px mono   →  2.20:1   FAILS  (small text: 4.5:1)

    The mono label is the word under every figure — «Vani», «Interni», «Classe
    energetica» — so at that ratio the strip states five numbers and does not say
    what any of them counts, on exactly the photographs that are brightest.

    At .68 the ground falls to 0.115 and the label at .78 white measures 4.65:1,
    with the figure at 6.38:1. Over a dark crop the change is barely visible; the
    tile is still translucent and the photograph still reads through it.

    A lightening gradient was tried on this tile first, for the sheen every other
    surface in §24 gets, and was removed: it raised the ground under the top of
    the tile, which is where the figure is. A panel over a photograph is the one
    place the sheen cannot be afforded, so it lives on `.pstats` — one pixel on
    the panel's own top edge, where there is no text.
*/
.pstat {
    background-color: rgba(8, 22, 29, .68);
    transition: background-color .3s var(--e);
}

.pstat b {
    font-variation-settings: 'opsz' 72;
    letter-spacing: -0.028em;
}

.pstat span { letter-spacing: 0.16em; color: rgba(255, 255, 255, 0.78); }

/* ---- the panel and the data sheet --------------------------------------- */

/* The energy class. A flat blue chip beside a flat blue bar; both now carry the
   light every other filled thing on the site carries, so the letter and the
   scale under it read as one instrument. */
.eclass {
    background-image: linear-gradient(180deg, var(--fill-top), var(--fill));
    box-shadow: var(--fill-sheen), 0 2px 8px -2px rgba(12, 68, 91, .45);
    font-weight: 600;
}

/*
    SOPRA I 420 PX, E NON PIU' OVUNQUE.

    Questa riga stava fuori da ogni media query, e siccome viene dopo la §20 —
    stessa specificita', «.dossier .sp» contro «.dossier .sp» — vinceva per
    ordine di scrittura anche sul telefono. Il risultato e' che la correzione
    della §20 non era mai stata applicata: a 390 px lo stile CALCOLATO diceva
    «padding: 22px 24px», non i 14/16 che quella sezione dichiara, ogni riga
    della scheda dati era alta 87,9 px e le nove righe facevano un blocco di
    867 px — il 102,7% di una finestra da 844, cioe' esattamente il difetto che
    il mosaico aveva prima di essere sistemato.

    Il numero grande resta dove serve, sopra i 420 px, dove la scheda ha due
    colonne e il respiro se lo puo' permettere.
*/
@media (min-width: 26.25rem) {
    .dossier .sp { padding: 1.375rem 1.5rem; }
}

/* ---- the gallery -------------------------------------------------------- */

.pviewer {
    border-radius: var(--radius-l);
    overflow: hidden;
    box-shadow: var(--sh), inset 0 0 0 1px var(--edge);
}

.pthumbs a {
    border-radius: 0.625rem;
    overflow: hidden;
    box-shadow: inset 0 0 0 1px var(--edge), var(--sh-0);
    transition: transform 0.3s var(--e), box-shadow 0.3s var(--e);
}

.pthumbs a:hover { transform: translateY(-3px); box-shadow: inset 0 0 0 1px var(--edge-2), var(--sh); }

.pvideo__stage {
    border-radius: var(--radius-l);
    overflow: hidden;
    box-shadow: var(--sh);
}

.pvideo__play {
    background-image: linear-gradient(180deg, var(--fill-top), var(--fill));
    box-shadow: var(--fill-sheen), 0 6px 22px -6px rgba(12, 68, 91, .6);
}

/* ---- the enquiry --------------------------------------------------------

   The end of the page and the only thing on its band. It was a white rectangle
   with a soft blur under it; it is the object every path through this site ends
   at, so it gets the deepest surface on the page. */

.penquiry__in {
    border-radius: var(--radius-xl);
    box-shadow: var(--sh-2), inset 0 0 0 1px var(--edge);
}

.penquiry .form__title {
    letter-spacing: -0.032em;
    font-variation-settings: 'opsz' 132;
}

/* ---- the enquiry card's own fields --------------------------------------

   §18 fixed what `--deep-blue` broke. One undeclared token was left: the
   transition on the field reads `var(--transition)`, and `--transition` is
   declared in `admin.css` and nowhere else — so on the public site the whole
   `transition` declaration is invalid at computed-value time and is dropped. The
   fields on the most important form on the site changed state instantly while
   every other field on the site eased. Written out, and given the same well and
   the same ring §24 gives the shared control. */

/* IL RAGGIO NON SI DICHIARA PIU' QUI. Era `12px`, scritto a mano, e faceva
   quello che la §3 della specifica vieta: i campi del modulo a 12 e quelli della
   scheda del periodo, sullo stesso schermo, a 6. Per un po' non si e' visto
   perche' una riga della §28.1 lo copriva di rimbalzo — `.p-property
   .form__field` — e quella riga se n'e' andata insieme alla sua giustificazione.
   Il raggio dei campi e' uno solo e sta in site.css §27.9. */
.penquiry .form__field {
    border-width: 1px;
    padding: 0.875rem 1rem;
    box-shadow: inset 0 1px 2px rgba(8, 22, 29, .045);
    transition: border-color .2s, box-shadow .2s, background-color .2s;
}

.penquiry .form__field:focus {
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--blue) 16%, transparent),
                inset 0 1px 2px rgba(8, 22, 29, .04);
}

.penquiry select.form__field {
    padding-right: 2.75rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23556b77' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.9375rem center;
    background-size: 1.0625rem 1.0625rem;
}

.penquiry .form__consent {
    box-shadow: inset 0 0 0 1px var(--edge);
    background: color-mix(in srgb, var(--text) 3.5%, transparent);
}

/* The reference pill. A flat blue wash with blue text; it is the first thing the
   card says and it now has an edge to say it inside. */
.penquiry .prefill {
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--blue) 24%, transparent);
    background: color-mix(in srgb, var(--blue) 10%, transparent);
}

/* ==========================================================================
   25. THE STAY, AND THE MONTHS AHEAD — the two blocks only a lodging has

   Contract CTR-2026-0817 art. 2 letter b. A tourist let is not a second design
   language: it is the property page with a different dossier and two more bands,
   and everything below either reuses a component the page already has (`.specs`,
   `.chips`, `.prose`) or is the smallest new thing that will do.

   The chips are the one reuse worth stating, because it is a REASSIGNMENT rather
   than a copy. `.chip` is a dark pill on the hero's pale ground; the amenities sit
   on white in the middle of the page, so they take the paper ground and the ink,
   and the class keeps its shape while the role tokens change under it — which is
   the mechanism §1 of site.css exists for.
   ========================================================================== */

/* ------------------------------------------------- 25.1 what you get, and how

   Two, three or four blocks depending on what the agency filled in, so the grid
   is `auto-fit` on a 15rem floor rather than a column count: an apartment with
   amenities and nothing else must not sit in a quarter of the band with three
   holes beside it. */
.pstay__grid {
    display: grid;
    gap: 34px 44px;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    margin-top: 30px;
}

/* The house rules are prose and the other three are lists, so they are not in the
   same container at all. Spanning `1 / -1` inside the grid looked equivalent and
   was not: `auto-fit` collapses a track only when NOTHING occupies it, and a
   full-width block occupies every track — so a fourth, empty column stayed open
   and squeezed the three lists into 265px each. */
.pstay__prose { margin-top: 40px; }

.pstay__h {
    margin: 0 0 14px;
    font-family: var(--d);
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -.012em;
    color: var(--heading);
}

.pstay__h--second { margin-top: 26px; }

/*
    ONE COLUMN, ALWAYS, inside these blocks.

    `.specs` is the site's specification list and it goes to two columns above
    37.5rem — which is right where it is used, across the full width of the data
    sheet. Here it sits inside a track of the stay grid, roughly 360px on a
    laptop, and the media query fires on the VIEWPORT rather than on the
    container: two columns of 170px turned «€ 2 a persona, a notte» into four
    lines and «Check-in / check-out» into three, with an empty cell beside the
    odd row.

    Container queries would say this properly. The override says it in one line
    and works everywhere.
*/
.pstay__block .specs { grid-template-columns: minmax(0, 1fr); }

/* The cells lose the width they were padded for. */
.pstay__block .sp { padding: 14px 16px; gap: 12px; }

/* The amenities on the page's own ground, not the hero's. `.chip` gives the
   shape; these four declarations give it the role it has here. */
.pstay__block .chips { margin-top: 0; }

.pstay__block .chip {
    background: var(--ground-2);
    background-image: none;
    color: var(--text);
    box-shadow: inset 0 0 0 1px var(--edge);
    font-weight: 500;
}

/* A cost the guest may decline reads differently from one they cannot. It is a
   word and not a colour: «(facoltativo)» is the whole information, and a green
   dot would have needed a legend. */
.pstay__opt {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-3);
}

/* Seventy words of house rules is not the same measure as a property
   description: it is a list of conditions read once, so it sits a size down and
   at the tighter leading of a note. */
.prose--small { font-size: 15.5px; line-height: 1.62; }

.prose--small p { margin: 0 0 12px; }

.prose--small p:last-child { margin-bottom: 0; }

/* ------------------------------------------------------ 25.2 the months ahead

   FOUR SMALL MONTHS, and «small» is the design rather than a constraint. The
   panel's calendar is a surface somebody writes on and its cells are 40px because
   they are targets; this one is read from across a page and never touched, so the
   cells are 26px and the whole of August fits beside the whole of September.

   TWO STATES AND NOT FOUR. Blocked, on hold and booked are the agency's own
   distinctions and none of them is available to a visitor, so all three read as
   taken — see the template for why publishing the difference would invite exactly
   the telephone call the distinction exists to avoid. */
/*
    IL CALENDARIO NON C'E' PIU', e qui c'erano le sue novanta righe.

    `.pfree__months`, `.mini`, `.mini__caption`, `.mini__head`, `.mini__cell` e i
    suoi quattro stati: quattro mesi di disponibilita' in sola lettura sulla
    pagina pubblica di un alloggio. Tolti su decisione del proprietario — un
    calendario e' uno strumento di lavoro, e il ragionamento per esteso sta in
    app/Http/property.php, dove i quattro mesi venivano costruiti.

    CANCELLATE E NON LASCIATE LI'. Un foglio di stile e' un file che il browser
    scarica su ogni scheda immobile, e novanta righe per una griglia che nessun
    documento stampa piu' sono peso vero, non disordine. Se il calendario dovesse
    tornare, torna con il suo template e con il suo stile: entrambi sono in questo
    commit, e `git log` sa dove.

    `.pfree__note` — la riga «il calendario e' indicativo» — se n'e' andata con
    lui: senza calendario non c'e' niente di cui dire che e' indicativo.
*/


/* ==========================================================================
   26. IL RIDISEGNO DELLA SCHEDA — apertura, mosaico, card

   Che cosa è cambiato nel template, perché questo blocco non si legge senza:

   · LA COPERTINA A TUTTA PAGINA NON C'È PIÙ. Era una fotografia alta quanto lo
     schermo su fondo notte, con il titolo e il prezzo scritti sopra. Al suo posto
     l'apertura è chiara e sta dentro la griglia: sopracciglio, titolo, pastiglia
     di stato, riferimento e prezzo come TESTO — non sopra un cielo — e poi il
     mosaico.
   · LA GALLERIA PIÙ IN BASSO NON C'È PIÙ. Era un palcoscenico con la striscia di
     pollici e ristampava la copertina: due volte la stessa immagine, e la prima
     domanda che uno si fa — com'è il resto? — a due schermate di distanza.
   · LE QUATTRO BANDE SONO DIVENTATE UNA COLONNA DI CARD sopra un fondo solo. È il
     modo in cui il cruscotto tiene insieme informazioni diverse, e ha un effetto
     che non è di stile: con le bande la spalla poteva stare appiccicata alla
     PRIMA soltanto, perché ogni banda successiva ricominciava a tutta larghezza.
     Adesso accompagna tutta la lettura.
   · LA LASTRA NERA DEL PREZZO È DIVENTATA UNA CARD CHIARA. Era giusta finché la
     pagina si apriva sul nero; con un'apertura chiara era l'unica cosa scura
     della pagina, cioè un buco.

   Le regole qui sotto vincono su quelle delle sezioni 1–25 per ordine di
   sorgente, che è la convenzione di questo foglio: niente viene cancellato sopra,
   e la passata si legge, si rivede e si annulla in un posto solo.
   ========================================================================== */

/* --------------------------------------------------- 26.1 l'apertura chiara */

.popen {
    padding-top: clamp(1.75rem, 3.5vw, 2.75rem);
    padding-bottom: clamp(2rem, 4vw, 3rem);
}

.popen__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

/* Il prezzo va a destra solo quando c'è una destra. Sotto i 60rem sta sotto il
   titolo, che è dove lo si legge su un telefono: nessuno tiene il pollice in alto
   a destra per leggere una cifra. */
@media (min-width: 60rem) {
    .popen__head {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: end;
        gap: 2.5rem;
    }

    .popen__aside { text-align: right; }
}

.popen__id { min-width: 0; }

.popen h1 {
    margin: 0.625rem 0 0;
    font-size: clamp(1.9rem, 4.2vw, 3.1rem);
    line-height: 1.06;
    letter-spacing: -0.03em;
    color: var(--heading);
    text-wrap: balance;
}

/*
    LA RIGA SOTTO IL TITOLO. Tre cose in fila e un solo peso: lo stato, il
    riferimento, la tipologia. Il riferimento è in mono perché è un codice che si
    detta al telefono, e i codici stanno in mono su tutto questo progetto.
*/
.popen__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.875rem;
    margin: 0.875rem 0 0;
    font-size: 0.8125rem;
    color: var(--text-2);
}

.popen__ref {
    font-family: var(--m);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    color: var(--text-3);
}

.popen__type {
    position: relative;
    padding-left: 0.875rem;
}

.popen__type::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--text-3);
    transform: translateY(-50%);
}

/*
    LA PASTIGLIA DI STATO CON IL PUNTO — il modo in cui il pannello scrive uno
    stato in ogni sua schermata, portato di qua.

    Il punto NON è l'informazione: la parola accanto lo è. È il motivo per cui è
    `aria-hidden` per costruzione (è uno ::before) e per cui la pastiglia funziona
    identica in bianco e nero.
*/
.ptag {
    display: inline-flex;
    align-items: center;
    gap: 0.4375rem;
    padding: 0.25rem 0.625rem 0.25rem 0.5rem;
    border-radius: 99px;
    font-family: var(--m);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
}

.ptag::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

.ptag--live {
    background: var(--blue-l);
    color: var(--blue-3);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--blue-3) 18%, transparent);
}

/* Un affare chiuso non è un errore: è un fatto. Grigio, non rosso — il rosso su
   questo sito vuol dire «hai sbagliato tu». */
.ptag--closed {
    background: var(--ground-2);
    color: var(--text-2);
    box-shadow: inset 0 0 0 1px var(--edge-2);
}

/* Il prezzo. Nella lastra nera era bianco su nero e faceva la sua figura; su
   fondo chiaro è la cosa più scura e più grande della riga, che è la stessa
   gerarchia ottenuta con meno rumore. */
.popen__price {
    margin: 0;
    font-family: var(--d);
    font-size: clamp(1.75rem, 3.4vw, 2.6rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.035em;
    font-variation-settings: 'opsz' 96, 'SOFT' 0, 'WONK' 0;
    color: var(--price);
    white-space: nowrap;
}

/* «Prezzo su richiesta» è una frase e non una cifra: composta come una cifra
   diventa un prezzo che non esiste. */
.popen__price--request {
    font-family: var(--t);
    font-size: clamp(1rem, 1.6vw, 1.25rem);
    font-weight: 500;
    letter-spacing: 0;
    font-variation-settings: normal;
    color: var(--text-2);
    white-space: normal;
}

/*
    Il comando condividi non è più su una fotografia: è un bottone fantasma in
    una riga di testo, quindi perde il vetro scuro — che era tarato su un cielo —
    e prende il bordo degli altri comandi del sito. Il bordo bianco al 28% su
    fondo chiaro era invisibile, ed è quello che lo faceva sembrare una macchia
    grigia appoggiata.
*/
.popen__aside .pshare { margin-top: 0.875rem; }

@media (min-width: 60rem) {
    .popen__aside .pshare { display: inline-block; }
}

.popen__aside .pshare__button,
.popen__aside .pshare__native {
    border-color: transparent;
    background-color: var(--card);
    background-image: none;
    color: var(--text-2);
    box-shadow: inset 0 0 0 1px var(--line-2), var(--sh-0);
    backdrop-filter: none;
}

.popen__aside .pshare__button:hover,
.popen__aside .pshare__native:hover {
    background-color: var(--card);
    color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent), var(--sh);
}

.popen__aside .pshare__icon { stroke: currentColor; }

/* ------------------------------------------------------- 26.2 il mosaico */

/*
    CINQUE RIQUADRI, IL PRIMO GRANDE QUANTO QUATTRO — che e' la forma di PRIMA.
    Quella che si vede oggi e' scritta nella §28.2: quattro riquadri, uno grande a
    sinistra e tre in colonna a destra. Quello che resta qui e' l'impianto — le
    tracce, il ritaglio, la striscia del telefono — e la §28.2 gli da' la forma.

    La griglia è 4 x 2 e il primo riquadro ne occupa 2 x 2. È la proporzione che
    tutti i portali usano e non è un caso: la fotografia grande resta abbastanza
    grande da valere, e le quattro piccole bastano a dire se c'è un giardino, un
    bagno rifatto e una vista, che sono le tre cose che decidono se uno scrive.

    Ogni traccia è `minmax(0, 1fr)`, compresa la colonna singola del telefono:
    il minimo automatico di una traccia `auto` è il suo contenuto, e una
    fotografia dentro una traccia `auto` non si lascia rimpicciolire.
*/
.pmosaic {
    position: relative;
    margin-top: 0;
}

.pmosaic__grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pmosaic__cell { min-width: 0; }

/* Il primo riquadro occupa il quadrato di sinistra. */
.pmosaic__cell:first-child {
    grid-column: span 2;
    grid-row: span 2;
}

.pmosaic__tile {
    position: relative;
    display: block;
    width: 100%;
    height: 100%;
    aspect-ratio: 3 / 2;
    overflow: hidden;
    border-radius: var(--radius);
    background: var(--ph-a);
}

/* Il riquadro grande è quadrato, non 3:2: deve riempire due righe di riquadri
   3:2 più il loro spazio, e una proporzione sbagliata qui lascia una fascia
   vuota alta dieci pixel sotto la fotografia. */
.pmosaic__cell:first-child .pmosaic__tile { aspect-ratio: auto; }

.pmosaic__tile > .image,
.pmosaic__tile > .ph {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

/*
    L'ANELLO A RIPOSO NON SI DICHIARA PIU' QUI.

    Disegnava intorno a ogni fotografia del mosaico lo stesso anello che la §24.5
    di site.css dava a ogni fotografia del progetto. Il mockup non incornicia le
    fotografie — «hanno lo stesso raggio del contenitore, senza cornice», §3
    della specifica — e site.css §27.9 lo spegne per tutto il sito, mosaico
    compreso.

    Quella riga non poteva pero' arrivarci: questo foglio e' caricato DOPO
    site.css, e a pari specificita' vince chi viene dopo. L'anello restava
    disegnato e la regola comune sembrava non funzionare. Tolto qui, la sola voce
    che parla dell'anello e' quella comune.

    Il pseudo-elemento resta, perche' e' il velo del passaggio del mouse qui
    sotto: senza `content` e `inset` non c'e' niente da illuminare.
*/
.pmosaic__tile::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    border-radius: inherit;
    transition: box-shadow .3s var(--e);
}

.pmosaic__tile:hover::after { box-shadow: inset 0 0 0 2px var(--accent); }

.pmosaic__tile:focus-visible { outline-offset: 3px; }

/* La fotografia si avvicina appena: 1.04 e non 1.07 come su una card, perché qui
   i riquadri sono cinque e cinque zoom insieme sono un acquario. */
.pmosaic__tile .image { transition: transform .6s var(--e); }
.pmosaic__tile:hover .image { transform: scale(1.04); }

/*
    QUANDO LE FOTOGRAFIE SONO MENO DI CINQUE la griglia si adatta invece di
    lasciare buchi. Una casa con due fotografie è la normalità nella settimana in
    cui l'agenzia la carica, e un mosaico con tre celle vuote sembra rotto.
*/
.pmosaic__grid--1 { grid-template-columns: minmax(0, 1fr); }
.pmosaic__grid--1 .pmosaic__cell:first-child { grid-column: 1; grid-row: 1; }
.pmosaic__grid--1 .pmosaic__tile { aspect-ratio: 3 / 2; }

.pmosaic__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pmosaic__grid--2 .pmosaic__cell:first-child { grid-column: 1; grid-row: 1; }
.pmosaic__grid--2 .pmosaic__tile { aspect-ratio: 3 / 2; }

.pmosaic__grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pmosaic__grid--3 .pmosaic__cell:first-child { grid-column: span 2; grid-row: span 2; }

/*
    LA FORMA CON QUATTRO FOTOGRAFIE NON SI SCRIVE PIU' QUI.

    Diceva «una grande 2 x 2 e le piccole intorno», che era il mosaico di prima.
    La §28.2 di questo stesso foglio dice «una grande 2 x 3 e tre in colonna»,
    che e' la forma del mockup — e lo dice con lo stesso selettore, alla stessa
    specificita', qualche centinaio di righe piu' sotto.

    Due regole di pari peso sullo stesso selettore: vinceva la seconda, e la
    prima restava a dire il contrario a chi legge il foglio. Una riga che il
    browser scarta ma che un lettore crede vera e' peggio di una riga assente.
*/

/*
    SUL TELEFONO IL MOSAICO NON È UNA GRIGLIA: è una fotografia grande e una
    striscia che scorre di lato. Cinque riquadri in griglia su 390 px sono cinque
    francobolli, e un francobollo di una cucina non è l'informazione «c'è una
    cucina» — è rumore.
*/
@media (max-width: 47.99rem) {
    .pmosaic__grid {
        display: flex;
        gap: 0.375rem;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        /*
            Il gesto arriva fino al bordo dello schermo: una striscia che si ferma
            al margine del testo sembra una griglia venuta male.

            VENTI PIXEL SCRITTI A MANO, e non un token: la gronda di `.container`
            e `.wrap` in site.css §2 e' `padding: 0 20px`, un valore letterale che
            nessuna proprieta' personalizzata porta. Scrivere `var(--gutter)` qui
            faceva sempre cadere la regola sul suo valore di riserva, che e' il
            modo peggiore di avere ragione: funziona, e smette di funzionare senza
            dire niente il giorno in cui qualcuno dichiara `--gutter` con un altro
            valore. Il numero e' quello, ed e' scritto due volte perche' e' lo
            stesso numero.
        */
        margin-inline: -20px;
        padding-inline: 20px;
        scrollbar-width: none;
    }

    .pmosaic__grid::-webkit-scrollbar { display: none; }

    .pmosaic__cell {
        flex: 0 0 82%;
        scroll-snap-align: start;
    }

    .pmosaic__cell:first-child { flex-basis: 92%; }
    .pmosaic__tile { aspect-ratio: 3 / 2; }
    .pmosaic__cell:first-child .pmosaic__tile { aspect-ratio: 3 / 2; }
}

/*
    «Vedi tutte le N fotografie».

    `.vfull` in site.css lo inchioda a `left: 16px`, perché nella galleria di
    prima stava nell'angolo del palcoscenico. Qui deve stare nell'angolo in basso
    a destra del mosaico, e `left` VA AZZERATO ESPLICITAMENTE: con `left` e
    `right` entrambi dichiarati su un elemento assoluto, la larghezza non è più
    quella del contenuto — il bottone si allarga da un capo all'altro del
    mosaico. È esattamente quello che faceva.
*/
.pmosaic__all {
    position: absolute;
    left: auto;
    right: 0.875rem;
    bottom: 0.875rem;
    z-index: 3;
}

/* Sul telefono il mosaico è una striscia che scorre: un bottone appiccicato
   all'angolo scorre via con la prima fotografia. Sotto la striscia, in riga. */
@media (max-width: 47.99rem) {
    .pmosaic__all {
        position: static;
        margin-top: 0.75rem;
        background: var(--card);
        color: var(--text);
        backdrop-filter: none;
        box-shadow: inset 0 0 0 1px var(--line-2), var(--sh-0);
    }
}

.pmosaic--empty .image,
.pmosaic--empty .ph {
    width: 100%;
    border-radius: var(--radius);
}

/* -------------------------------------------- 26.3 la riga dei numeri */

/*
    Era bianca su una fotografia, dentro la banda scura. Adesso è una riga di
    riquadri chiari sotto il mosaico, con il quadrato dell'icona della §26.1 di
    site.css. Tre di quelle cifre, sopra un cielo sovraesposto, si leggevano a
    seconda della fotografia.
*/
.pstats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
    gap: 0.5rem;
    margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
}

/*
    DUE COLONNE E DUE RIGHE, non tre elementi in fila.

    `.pstat` era `display: flex` e i suoi tre figli — icona, cifra, etichetta —
    finivano uno accanto all'altro: «Casale  TIPOLOGIA» su una riga sola, che
    legge come due parole senza rapporto invece che come un valore e la sua
    unità. La griglia mette l'icona in una colonna sua, alta due righe, e
    impila la cifra sopra l'etichetta, che è come il pannello scrive un dato in
    ogni sua schermata.
*/
.pstat {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    column-gap: 0.75rem;
    min-width: 0;
    padding: 0.8125rem 1rem;
    border: 0;
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: inset 0 0 0 1px var(--edge), var(--sh-0);
}

.pstat svg { grid-row: span 2; }

/* Il quadrato dell'icona, la stessa misura che porta ogni riga della scheda
   dati: due componenti diversi con lo stesso segno sono un sistema. */
.pstat svg {
    box-sizing: border-box;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    padding: 8px;
    border-radius: 10px;
    background: var(--icon-box);
    box-shadow: inset 0 0 0 1px var(--edge);
    stroke: var(--icon-mark);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
    opacity: 1;
}

.pstat b {
    display: block;
    font-family: var(--d);
    font-size: 1.0625rem;
    font-weight: 400;
    line-height: 1.15;
    letter-spacing: -0.02em;
    font-variation-settings: 'opsz' 48, 'SOFT' 0, 'WONK' 0;
    color: var(--heading);
    font-variant-numeric: tabular-nums;
}

.pstat span {
    display: block;
    margin-top: 2px;
    font-family: var(--m);
    font-size: 0.625rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-3);
}

/* Una tipologia è una parola e non una cifra: nella famiglia del testo, non del
   display, o «Appartamento» a 17px in un serif ad alto contrasto occupa due
   righe dentro un riquadro alto una. */
.pstat--word b {
    font-family: var(--t);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0;
    font-variation-settings: normal;
    overflow-wrap: anywhere;
}

/* ------------------------------------------------------ 26.4 il corpo a card */

.pmain {
    background: var(--paper);
    padding-block: clamp(2rem, 4.5vw, 3.5rem);
}

.pgrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

@media (min-width: 65rem) {
    .pgrid {
        grid-template-columns: minmax(0, 1fr) 21.5rem;
        gap: 1.25rem;
    }
}

.pcol {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    min-width: 0;
}

/*
    LA CARD. È il componente del cruscotto: fondo bianco, filetto pieno, angolo
    largo, ombra corta. La testata è divisa dal corpo da una riga vera, perché
    con dodici card in colonna il titolo deve dire dove comincia una cosa senza
    che si legga.
*/
.pcard {
    min-width: 0;
    background: var(--card);
    border-radius: var(--radius-l);
    box-shadow: inset 0 0 0 1px var(--edge), var(--sh);
    overflow: hidden;
}

.pcard__head {
    padding: clamp(1.25rem, 2.4vw, 1.625rem) clamp(1.25rem, 2.6vw, 1.875rem) 1.0625rem;
    border-bottom: 1px solid var(--hair);
}

/* Il filetto di bronzo della §26.3 di site.css sta sotto una `.shead`, che qui
   non c'è: la testata di una card è un altro oggetto. Il segno però è lo stesso,
   ed è il sopracciglio a portarlo — un tratto per testata, come su tutto il
   resto del sito. */
.pcard__head .snum { color: var(--text-3); }

.pcard__head h2 {
    margin: 0.5rem 0 0;
    font-size: clamp(1.35rem, 2.2vw, 1.75rem);
    line-height: 1.14;
    letter-spacing: -0.024em;
    color: var(--heading);
}

.pcard__body { padding: clamp(1.25rem, 2.6vw, 1.875rem); }

/* La scheda dati porta la propria griglia con i propri filetti fino al bordo:
   una card dentro una card è un bordo di troppo. */
.pcard__body--flush { padding: 0; }

.pcard__body--flush .specs {
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/* Dentro una card la prosa non è più larga quanto la banda: la misura di riga la
   decide la colonna. */
.pcard .prose { max-width: 60ch; }

.pcard .prose > p:first-child { margin-top: 0; }
.pcard .prose > p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------- 26.5 la spalla chiara */

.side { min-width: 0; }

@media (min-width: 65rem) {
    .side {
        position: sticky;
        top: calc(var(--top-h) + var(--notice-h) + 1rem);
    }
}

/*
    LA LASTRA NERA DIVENTA UNA CARD.

    Non è un ammorbidimento: è la stessa gerarchia ottenuta con il contrasto
    giusto. Il prezzo resta la cosa più grande e più scura della colonna, ma
    adesso è inchiostro su bianco a 13.7:1 invece di bianco su nero dentro un
    rettangolo che non apparteneva a nessuna delle bande intorno.
*/
.pbox {
    background: var(--card);
    border-radius: var(--radius-l);
    box-shadow: inset 0 0 0 1px var(--edge), var(--sh);
    overflow: hidden;
}

.pbox__t {
    padding: 1.375rem 1.5rem 1.25rem;
    border-bottom: 1px solid var(--hair);
    background: none;
}

.pbox__p {
    margin: 0;
    font-family: var(--d);
    font-size: clamp(1.6rem, 2.6vw, 2rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.035em;
    font-variation-settings: 'opsz' 96, 'SOFT' 0, 'WONK' 0;
    color: var(--price);
}

.pbox__p--request {
    font-family: var(--t);
    font-size: 1.0625rem;
    font-weight: 500;
    letter-spacing: 0;
    font-variation-settings: normal;
    color: var(--text-2);
}

.pbox__r {
    margin: 0.5rem 0 0;
    font-family: var(--m);
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-3);
}

.pbox__a {
    display: grid;
    gap: 0.625rem;
    padding: 1.25rem 1.5rem 1.5rem;
    background: none;
}

.pbox__note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.375rem 0 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--text-3);
}

.pbox__note svg {
    flex: 0 0 auto;
    width: 15px;
    height: 15px;
    margin-top: 2px;
    stroke: var(--accent);
    stroke-width: 1.6;
    fill: none;
}

/* ------------------------------------------- 26.6 quello che ne consegue */

/* La banda della richiesta e quella del territorio erano separate dalla scheda
   dati da una banda bianca. Adesso sopra di loro c'è il fondo carta del corpo,
   quindi il primo stacco lo fa il colore e non serve altro. */
.penquiry { padding-top: clamp(2.5rem, 5vw, 4rem); }

/* Il soggiorno sta dentro una card e non più dentro una banda: perde il respiro
   della banda e prende quello della card. Le due righe che stavano qui per la
   disponibilità se ne sono andate con il calendario. */
.pstay__grid { gap: 1.75rem 2rem; }
.pstay__prose { margin-top: 1.75rem; }

/* La riga della località chiude la descrizione: dentro la card è un piede, non
   un blocco a sé. */
.psheet__where {
    margin: 1.5rem 0 0;
    padding-top: 1.125rem;
    border-top: 1px solid var(--hair);
}

/* ==========================================================================
   27. IL PERIODO DENTRO LA RICHIESTA

   Da quando il calendario non sta piu' sulla pagina pubblica, questi due campi
   sono l'unico posto in cui una data compare su una scheda. Sono raggruppati e
   non sparsi fra gli altri, perche' arrivo e partenza sono UNA domanda: due
   campi data in fila fra il telefono e il messaggio si leggono come due campi
   qualsiasi, e mezzo intervallo compilato e' il difetto piu' probabile.
   ========================================================================== */

.form__stay {
    padding: 1.125rem 1.25rem 1.25rem;
    border-radius: var(--radius);
    background: var(--ground-2);
    box-shadow: inset 0 0 0 1px var(--edge);
}

.form__stay-title {
    margin: 0 0 0.875rem;
    font-family: var(--m);
    font-size: 0.6875rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-3);
}

/*
    DUE COLONNE APPENA C'E' SPAZIO, e una sola sotto i 30rem.

    Il minimo e' 11rem e non 0: un campo data disegna il proprio calendario e il
    proprio separatore, e sotto quella misura Chrome e Safari tagliano l'anno
    senza dirlo. `minmax(0, 1fr)` su entrambe le tracce perche' il minimo
    automatico di una traccia `auto` e' il suo contenuto, e il contenuto qui e'
    un controllo che non si lascia rimpicciolire.
*/
.form__stay-fields {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.875rem 1rem;
}

@media (min-width: 30rem) {
    .form__stay-fields { grid-template-columns: repeat(2, minmax(11rem, 1fr)); }
}

.form__stay .form__hint { margin-top: 0.75rem; }

/* Il campo data non e' un campo di testo: disegna il proprio pulsante e il
   proprio separatore, e senza altezza minima resta piu' basso degli altri
   controlli del modulo. */
.form__stay input[type='date'] {
    min-height: 3rem;
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   28. IL MOCKUP DEL COMMITTENTE — la scheda diventa due colonne su bianco

   Il committente ha consegnato la schermata di una scheda appartamento. Da
   quella: briciole, mosaico, e sotto DUE COLONNE — il testo a sinistra, la
   scheda che verifica il periodo appiccicata a destra. La pagina e' bianca dalla
   prima all'ultima riga, e quello che separa i blocchi e' un filetto.

   CHE COSA SUPERA, DELLE VENTISETTE SEZIONI SOPRA, e perche' non e' cancellato:

   · le CARD (§26.4). Ogni blocco della colonna era una scatola con il bordo,
     l'ombra e una testata dentro un riquadro proprio. Nel mockup la colonna e'
     un foglio solo: dodici scatole in fila dentro una colonna larga 700 px
     disegnano dodici cornici dove serviva un filo. Restano `.pblock` e un
     filetto in cima.
   · i RIQUADRI DEI NUMERI (§26.3). «6 posti letto» dentro un rettangolo con il
     fondo e il bordo e' una cornice intorno a due parole. Diventa `.pfacts`, una
     riga di icone e cifre come nel disegno.
   · la LASTRA DEL PREZZO (§26.5). Diventa `.bcard` di site.css §27.5.5, che e' il
     componente condiviso con le altre pagine.

   Niente di tutto questo e' stato tolto dalle sezioni di sopra: questo foglio e'
   append-only da ventisette sezioni e la passata si legge, si rivede e si annulla
   in un posto solo. Le regole qui vincono per ordine di sorgente.

   I COLORI ARRIVANO DAI TOKEN DI RUOLO, come in tutto il progetto: qui non c'e'
   un solo valore letterale che non sia una velatura sopra una fotografia.
   ========================================================================== */

/* --------------------------------------------------- 28.1 una fascia sola */

/*
    La scheda apriva con quattro fondi in fila — bianco, carta, azzurro, blu
    scuro — per una pagina sola. Nel mockup e' bianca, e la sola banda di fondo
    diverso e' quella delle esperienze in coda, dove comincia un'altra cosa: due
    sezioni consecutive non condividono mai un fondo (docs/DESIGN.md §1).
*/
.popen {
    padding-top: clamp(1rem, 2vw, 1.75rem);
    padding-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

/*
    IL RAGGIO NON SI RISCRIVE QUI, E LA GIUSTIFICAZIONE CHE LO DICEVA NON E' PIU'
    VERA.

    C'erano due righe — `.p-property .cta` e `.p-property .form__field` — che
    riportavano a 6 px il bottone e il campo, con la motivazione che site.css se
    li scriveva a mano a 11 e 12 px e che nessun token li raggiungeva. Adesso li
    raggiunge: site.css §27.9 porta `.cta`, `.sbox__i`, `.sbox__go`,
    `.property-card__go` e `.form__field` a `var(--radius)` per tutto il sito, ed
    e' li' che la §3 della specifica va detta una volta sola.

    C'e' anche un motivo per cui non ci sarebbero dovute stare comunque:
    `.p-property` e' la classe del GUSCIO, non di questa pagina, e un foglio di
    pagina che si afferra al guscio per ridisegnare un componente condiviso e' un
    componente che cambia forma a seconda di dove lo si guarda.
*/

/* ------------------------------------- 28.2 il mosaico: una grande e tre */

/*
    UNA GRANDE A SINISTRA E TRE IN COLONNA A DESTRA, che e' la forma del disegno.
    Erano quattro piccole in un quadrato 2x2; il partial ne mostra tre, e qui la
    griglia diventa tre colonne per tre righe con la grande che ne occupa 2 x 3.

    Le tre piccole sono 3:2 e stanno in colonna, quindi la grande e' alta quanto
    tre di loro piu' due spazi: `aspect-ratio: auto` sul primo riquadro (§26.2) e'
    quello che glielo lascia fare, e una proporzione fissa qui lascerebbe una
    fascia vuota sotto la fotografia.
*/
.pmosaic { margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem); }

.pmosaic__grid--4 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.pmosaic__grid--4 .pmosaic__cell:first-child {
    grid-column: span 2;
    grid-row: span 3;
}

/*
    IL VELO «+N foto», dentro l'ultima cella.

    Stava FUORI dalla griglia e si posizionava calcolando la geometria: «tre
    colonne e mezzo rem di spazio, quindi la cella e' alta `(100% - 1rem) / 4.5`».
    Il calcolo era sbagliato in un modo che non si vede rileggendolo — una
    percentuale di ALTEZZA si risolve sull'altezza del contenitore, non sulla sua
    larghezza — e il velo usciva della misura sbagliata su ogni scheda del sito.

    Dentro la cella non c'e' niente da calcolare, e la regola vale per tutte e
    quattro le forme della griglia e anche per la striscia del telefono.

    Il fondo e' l'unico valore letterale qui intorno: e' una velatura sopra una
    fotografia, e una fotografia non ha un token di ruolo.
*/
.pmosaic__cell { position: relative; }

.pmosaic__veil {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: var(--radius);
    /*
        0,66 E NON 0,58. Il velo copre una fotografia, quindi il fondo peggiore
        possibile e' il bianco: a 0,58 il navy composto sul bianco fa
        rgb(120,127,141) e il «+1 foto» bianco sopra misura 4,01:1 — sotto il
        minimo di 4,5:1 per un testo che a 17 px non e' testo grande. A 0,66 il
        composto e' rgb(101,110,125) e il rapporto sale a 5,16:1, che regge
        anche sulla fotografia piu' chiara del catalogo.
    */
    background-color: rgba(22, 35, 58, 0.66);
    color: #fff;
    font: inherit;
    font-size: 1.0625rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    cursor: pointer;
}

.pmosaic__veil:hover { background-color: rgba(22, 35, 58, 0.78); }

.pmosaic__veil:focus-visible { outline: 2px solid #fff; outline-offset: -4px; }

/* Sul telefono il mosaico diventa una striscia che scorre, e il velo resta
   dov'e': dentro l'ultima cella. Non c'e' piu' niente da rimisurare — era proprio
   la misura calcolata a mano a rendere necessaria questa eccezione. */

/* ------------------------------------------------- 28.3 le due colonne */

/*
    La spalla si allarga e lo spazio fra le colonne raddoppia: nel mockup le due
    colonne sono due cose separate, non due metà di una griglia stretta. Sotto i
    65rem restano una sotto l'altra — una scheda di prenotazione larga 340 px
    accanto a una colonna di testo larga 300 non e' due colonne, e' due strisce.
*/
.pgrid { gap: clamp(2rem, 4vw, 3rem); }

@media (min-width: 65rem) {
    .pgrid {
        grid-template-columns: minmax(0, 1fr) 21rem;
        gap: clamp(2.25rem, 4vw, 3.25rem);
    }
}

/* Lo spazio fra i blocchi lo porta il blocco, insieme al suo filetto: dichiararlo
   due volte — qui e li' — vuol dire misurarlo due volte. */
.pcol { gap: 0; }

/* ---------------------------------------------------- 28.4 la testata */

.phead { min-width: 0; }

/* 30–34 px nel mockup, contro i 50 della copertina di prima: il titolo di una
   scheda non e' il titolo di una home, e sopra ha gia' le fotografie a dire di
   che casa si parla. */
.popen .phead h1 {
    margin: 0;
    font-size: clamp(1.625rem, 3vw, 2.125rem);
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: var(--heading);
    text-wrap: balance;
}

/* Una riga sola e un peso solo: lo stato, il luogo, il riferimento, la
   tipologia. Il riferimento e' un codice che si detta al telefono, quindi
   maiuscoletto spaziato — che nel mockup e' la forma di ogni etichetta. */
.phead__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.875rem;
    margin: 0.875rem 0 0;
    font-size: 0.8125rem;
    color: var(--text-2);
}

.phead__where {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

.phead__where svg {
    width: 0.9375rem;
    height: 0.9375rem;
    flex: 0 0 auto;
    stroke: var(--accent);
    stroke-width: 1.6;
    fill: none;
}

.phead__ref {
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-3);
}

/* Il punto fra due parole lo disegna il filetto e non un carattere: un separatore
   scritto nel template e' un carattere che va tradotto tre volte. */
.phead__type {
    position: relative;
    padding-left: 0.875rem;
}

.phead__type::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--text-3);
    transform: translateY(-50%);
}

/*
    Il comando condividi non sta piu' su una fotografia: perde il vetro scuro —
    che era tarato su un cielo — e prende il bordo degli altri comandi del sito.
    Il bordo bianco al 28% su fondo chiaro era invisibile, ed e' quello che lo
    faceva sembrare una macchia grigia appoggiata.

    E NON E' PIU' FIGLIO DELLA TESTATA, quindi il selettore non puo' essere
    `.phead`: nel mockup l'H1 e' seguito subito dalla riga dei dati (§4.10), e un
    bottone in mezzo spezzava in due la testata. Sta dopo la riga dei dati, che
    e' figlia di `.pcol` come lui — ed e' anche il posto giusto nel discorso: si
    manda a qualcuno una casa dopo aver letto che casa e'.

    `justify-self: start` PERCHE' ORA E' UNA CASELLA DELLA GRIGLIA. `.pcol` e' una
    griglia a una colonna, e un elemento in linea che diventa casella di griglia
    viene reso di blocco: il bottone, che dentro la testata si stringeva sul suo
    testo, si allargava da un capo all'altro della colonna. Un «Condividi» largo
    924 px e' il comando piu' grande della pagina, e non e' la cosa piu'
    importante che ci sia sopra.
*/
.pcol .pshare,
.pcol .pshare__native {
    margin-top: 1.125rem;
    justify-self: start;
}

.pcol .pshare__button,
.pcol .pshare__native {
    border-color: var(--hair);
    border-radius: var(--radius);
    background-color: var(--card);
    background-image: none;
    color: var(--text-2);
}

.pcol .pshare__button:hover,
.pcol .pshare__native:hover {
    background-color: var(--card);
    border-color: var(--accent);
    color: var(--accent);
}

/*
    E L'ANELLO DI MESSA A FUOCO SCENDE CON LORO.

    `.pshare__button:focus-visible` della §11 disegna l'anello con `--blue-4`,
    che e' il token dell'azzurro COME TESTO SU FONDO SCURO: era giusto quando
    questo bottone stava sopra una fotografia. Sul bianco della colonna
    #a8c6ea misura 1,74:1 contro il fondo — sotto il minimo di 3:1 per un
    segno non testuale, e praticamente invisibile — mentre ogni altro comando
    della pagina prende `--focus` e sta a 10,8:1. Un contorno di messa a fuoco
    che non si vede e' un contorno che non c'e'.
*/
.pcol .pshare__button:focus-visible,
.pcol .pshare__native:focus-visible {
    outline-color: var(--focus);
}

.pcol .pshare__icon { stroke: currentColor; }

/* ------------------------------------------------ 28.5 la riga dei dati */

/*
    Quattro dati con l'icona, in riga, sotto il titolo: e' la prima cosa che si
    guarda dopo le fotografie e prima di una parola di prosa. Quali quattro lo
    decide il template, e dipende da che cosa e' — chi compra chiede vani e
    classe energetica, chi affitta per una settimana chiede quanti ci dormono.
*/
.pfacts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem 1.5rem;
    margin: 1.25rem 0 0;
    padding: 0;
    list-style: none;
}

.pfacts__i {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    font-size: 0.9375rem;
    color: var(--text);
}

.pfacts__i svg {
    width: 1.125rem;
    height: 1.125rem;
    flex: 0 0 auto;
    stroke: var(--accent);
    stroke-width: 1.5;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
}

.pfacts__i b {
    font-weight: 600;
    color: var(--heading);
    font-variant-numeric: tabular-nums;
}

.pfacts__i span { color: var(--text-2); }

/* Una classe energetica e' una lettera, non una cifra: niente cifre tabulari,
   che su una «B» sola non fanno nulla e su una «A4» spaziano male. */
.pfacts__i--word b { font-variant-numeric: normal; }

/* -------------------------------------------------------- 28.6 i blocchi */

/*
    Il blocco al posto della card: un filetto in cima, il respiro sopra e sotto,
    e niente cornice. Dodici cornici dentro una colonna larga 700 px sono dodici
    scatole; un filetto dice la stessa cosa — qui comincia un'altra cosa — e non
    disegna niente.
*/
.pblock {
    min-width: 0;
    margin-top: clamp(1.75rem, 3vw, 2.5rem);
    padding-top: clamp(1.75rem, 3vw, 2.5rem);
    border-top: 1px solid var(--hair);
}

/* 19–21 px serif nel mockup: piu' piccolo del titolo della pagina e piu' grande
   del testo, che e' esattamente il lavoro che fa. */
.pblock__t {
    margin: 0 0 1rem;
    font-family: var(--d);
    font-size: clamp(1.125rem, 1.8vw, 1.3125rem);
    font-weight: 400;
    line-height: 1.25;
    letter-spacing: -0.015em;
    color: var(--heading);
}

/* Una seconda testata dentro lo stesso blocco — «Come si arriva» sotto «Regole
   della casa» — vuole lo stacco che il filetto darebbe se fossero due blocchi. */
.pblock__t--second { margin-top: 1.75rem; }

/*
    La prosa scende a 15 px, che e' la misura del mockup. Era 17,5, e 17,5 dentro
    una colonna di 700 px e' una riga da 75 caratteri: si legge, ma non e' il
    testo che il disegno ha in mente. Il primo paragrafo resta piu' grande — e'
    la regola della §24 di site.css, ed e' quello che fa leggere una descrizione
    come un'apertura invece che come un muro.
*/
/*
    LA MISURA E' 52ch E NON 64, e la differenza e' che `ch` non e' un carattere.

    `ch` e' la larghezza dello ZERO, e in Inter lo zero e' molto piu' largo
    della media delle minuscole italiane. Risultato: 64ch si risolveva in
    606 px, e contando i caratteri riga per riga dentro quei 606 px la riga piu'
    lunga della descrizione ne portava 84 sulla vendita e 84 sull'alloggio —
    nove oltre il tetto di 75 che questa pagina si da'. Il conto del commento
    qui sotto era fatto sul corpo del PRIMO paragrafo, che e' 17 px; i paragrafi
    che seguono sono 15, e a 15 px in 606 px ci sta un'altra riga di parole.

    52ch fa 492 px — 32,8 em a 15 px — e la riga piu' lunga misurata scende a
    75 sulla vendita e 71 sull'alloggio.
*/
.pcol .prose {
    max-width: 52ch;
    font-size: 0.9375rem;
    line-height: 1.72;
}

.pcol .prose p:first-child { font-size: 1.0625rem; line-height: 1.65; }
.pcol .prose > p:first-child { margin-top: 0; }
.pcol .prose > p:last-child { margin-bottom: 0; }

/* --------------------------------- 28.7 i servizi e le informazioni utili */

/* `.svcs` e `.useful` sono i componenti di site.css §27.5.3 e §27.5.4: qui c'e'
   solo quello che questa pagina ci mette dentro e che il componente non poteva
   sapere — una coppia etichetta/valore invece di una riga sola di testo. */
.pblock .svcs { gap: 0.75rem 1.5rem; }

/*
    UNA COPPIA, NON UNA FRASE. «Notti minime 5» e «Pulizia finale 70 € a
    soggiorno» sono un'etichetta e un valore, e allineare i valori a destra dentro
    una misura corta e' quello che li rende confrontabili con un colpo d'occhio —
    che e' l'unica cosa che uno fa con un elenco di costi.

    La misura e' corta apposta: con il valore a filo destro di una colonna larga
    700 px, l'etichetta e la sua cifra finiscono a mezzo schermo di distanza.
*/
.pblock .useful { max-width: 34rem; }

.useful__i {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.125rem 1rem;
}

.useful__l { color: var(--text-2); }

.useful__v {
    font-weight: 600;
    color: var(--heading);
    text-align: right;
}

/* «(facoltativo)» e' una postilla dell'etichetta, non una seconda etichetta. */
.useful__opt { color: var(--text-3); }

/*
    L'ETICHETTA DELLA SCHEDA DATI TORNA NELLA SCALA.

    Misurata: 9,5 px — il valore che `.sp dt` porta da site.css §24, e che la
    §2 di questo foglio ripete. E' un maiuscoletto mono con 0,14em di
    spaziatura, cioe' la forma di testo che si legge peggio, alla misura piu'
    piccola della pagina: l'occhiello del progetto sta fra 11 e 12 px e questo
    stava il 16% sotto il fondo scala. Undici, che e' la stessa misura di
    `.snum` e di `.ptag` — gli altri due occhielli della pagina — cosi' i tre
    segni piu' piccoli della scheda dicono la stessa cosa con la stessa voce.

    Serve DUE classi: `.sp dt` di site.css vale (0,1,1) e `.dossier__label` da
    solo (0,1,0), quindi da solo perderebbe senza lasciare traccia.
*/
.dossier .dossier__label { font-size: 0.6875rem; }

/* La scheda dati prende il bordo pieno del mockup al posto dell'anello quasi
   invisibile e dell'ombra corta: e' l'unico blocco della colonna che ha una
   cornice, e ce l'ha perche' e' una griglia di righe, non una lista. */
.pblock .specs { box-shadow: inset 0 0 0 1px var(--hair); }

/* -------------------------------------------------------- 28.8 la spalla */

/*
    La spalla intera resta appiccicata, `.bcard` compresa: il componente si
    dichiara `position: sticky` per conto suo (site.css §27.5.5) perche' altrove
    e' figlio diretto della griglia, ma qui sopra di lui c'e' gia' un contenitore
    appiccicato e due sticky annidati vogliono dire che quello di dentro non ha
    dove andare. Vince quello di fuori, cosi' le rassicurazioni salgono con la
    scheda invece di scorrere via da sole.
*/
.side { min-width: 0; }

@media (min-width: 65rem) {
    .side {
        position: sticky;
        top: calc(var(--top-h) + var(--notice-h) + 1.25rem);
    }
}

/*
    SOTTO I 65rem LA SPALLA NON E' PIU' UNA SPALLA — MA RESTA UNA SCHEDA.

    Quando le due colonne si chiudono, `.side` diventa larga quanto la pagina e
    tutto quello che ha dentro con lei. Misurato a 1024: il campo «Dal» era
    largo 894 px. Una data ne chiede centottanta, e la barra dei filtri del
    catalogo — che usa gli stessi `.sbox__f` — a quella stessa larghezza li
    disegna fra 179 e 230 px. Alla stessa misura erano il bottone «Cerca in
    queste date», il numero di telefono e il collegamento al modulo: bersagli
    larghi mezzo schermo, che a premerli sembrano bande e non bottoni.

    Il tetto e' 24rem contro le 21 della spalla vera: la scheda resta la stessa
    cosa che si vede a 1440, appoggiata al filo sinistro della colonna come
    tutto il resto della pagina, invece di trasformarsi in una fascia. Sul
    telefono non cambia niente — a 390 la colonna misura 350 px e il tetto non
    la tocca.
*/
@media (max-width: 64.99rem) {
    .side { max-width: 24rem; }
}

.side .bcard { position: static; }

.side .bcard__t { margin-bottom: 0.5rem; }

/* Il prezzo e' la cosa piu' grande e piu' scura della colonna. Nella lastra nera
   era bianco su nero e faceva la sua figura; su fondo chiaro e' inchiostro su
   bianco, che e' la stessa gerarchia con meno rumore. */
.pside__price {
    margin: 0;
    font-family: var(--d);
    font-size: clamp(1.5rem, 2.4vw, 1.875rem);
    font-weight: 400;
    line-height: 1;
    letter-spacing: -0.03em;
    font-variation-settings: 'opsz' 60, 'SOFT' 0, 'WONK' 0;
    color: var(--price);
}

/* «Tariffa su richiesta» e' una frase e non una cifra: composta come una cifra
   diventa un prezzo che non esiste. */
.pside__price--request {
    font-family: var(--t);
    font-size: 1.0625rem;
    font-weight: 500;
    letter-spacing: 0;
    font-variation-settings: normal;
    color: var(--text-2);
}

.pside__ref {
    margin: 0.4375rem 0 1.125rem;
    font-size: 0.6875rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-3);
}

/*
    Il telefono con il numero come etichetta, sotto il bottone pieno: un comando
    che dice «chiamaci» e nasconde il numero e' un comando che nessuno preme. E'
    il secondo modo, quindi ha il peso del secondo modo — un contorno, non un
    pieno.
*/
.pside__way {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 2.75rem;
    margin-top: 0.625rem;
    padding: 0 1rem;
    border: 1px solid var(--hair);
    border-radius: var(--radius);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    transition: border-color 0.2s var(--e), color 0.2s var(--e);
}

.pside__way svg {
    width: 1rem;
    height: 1rem;
    flex: 0 0 auto;
    stroke: var(--accent);
    stroke-width: 1.6;
    fill: none;
}

.pside__way:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* --------------------------------------------------------- 28.9 il modulo */

/*
    Il modulo era una banda azzurra per conto suo, in fondo alla pagina. Adesso e'
    l'ultimo blocco della colonna del testo, e la spalla con il prezzo gli sta
    accanto mentre uno scrive: `.penquiry` resta come nome perche' e' anche
    `id="enquiry"`, l'ancora che la spalla e la barra del telefono puntano.

    Il padding-top e' dichiarato sulla coppia di classi e non su una sola: la
    §26.6 ne scrive uno per `.penquiry` e la §28.6 un altro per `.pblock`, e con
    due regole di pari peso sullo stesso elemento vince l'ultima letta — che e'
    un modo di avere ragione per caso.
*/
.pblock.penquiry { padding-top: clamp(2rem, 3.5vw, 3rem); }

.penquiry .form__title {
    margin: 0 0 0.5rem;
    font-size: clamp(1.5rem, 2.6vw, 2rem);
    line-height: 1.15;
}

.penquiry .lead {
    max-width: 46rem;
    margin: 0 0 1.5rem;
    font-size: 0.9375rem;
}

.penquiry .prefill { margin-bottom: 0.875rem; }

/*
    TRE CAMPI IN RIGA — nome, email, telefono — che e' la prima riga del modulo
    nel mockup. Il partial dichiara il nome «largo» perche' sulle altre pagine il
    modulo e' a due colonne e un nome e cognome dentro mezza colonna sta stretto;
    qui le colonne sono tre e il nome ne vuole una.

    `:has()` invece di un `nth-child`: fra i figli del modulo ci sono i campi
    nascosti, la trappola e un riferimento che c'e' solo qualche volta, quindi
    contare le posizioni vuol dire contare male il giorno in cui il partial ne
    aggiunge uno. Il selettore dice quello che intende — il blocco che contiene
    l'etichetta del nome — ed e' vero per costruzione.
*/
@media (min-width: 43.75rem) {
    .penquiry .form { grid-template-columns: repeat(3, minmax(0, 1fr)); }

    .penquiry .form__wide:has(> label[for$='-name']) { grid-column: auto; }
}

/* Il bottone a tutta larghezza in fondo, come nel disegno: e' l'ultima cosa che
   si preme su questa pagina e non deve essere una pastiglia in mezzo al bianco. */
.penquiry .form__actions { align-items: stretch; }
.penquiry .form__actions .cta { width: 100%; justify-content: center; }

/* --------------------------------------------------- 28.10 il territorio */

/* La banda era blu scura con il bordo tagliato. Il mockup non ha ne' fasce notte
   ne' angoli obliqui, e l'unica cosa scura del disegno e' il pie' di pagina: una
   fascia navy qui attaccava direttamente il navy del piede. Su carta resta un
   fondo diverso da quello della sezione sopra, che e' la regola delle bande. */
.pexp { padding-block: clamp(2.5rem, 5vw, 4.5rem); }

.pexp .shead { margin-bottom: clamp(1.5rem, 3vw, 2rem); }

/*
    «INTORNO A QUESTA CASA» NON PUO' ESSERE PIU' GRANDE DEL NOME DELLA CASA.

    L'h2 del sito e' `clamp(1.9rem, 4.2vw, 3.3rem)` (site.css §2), ed e' tarato
    su pagine il cui titolo e' della stessa famiglia: sul catalogo l'h1 misura
    54,4 px e il sopracciglio di sezione 52,8, che e' una gerarchia. Qui no: il
    mockup porta il titolo dell'annuncio a 34 px (§28.4), e con l'h2 fermo a
    52,8 la cosa piu' grande della scheda diventava il sopracciglio della banda
    in coda — 1,55 volte il nome dell'immobile e 1,76 volte il prezzo. Su una
    pagina che vende una casa, le parole piu' grandi erano quelle del rimando.

    Misure prese: 52,8 px a 1440, 52,8 a 1024, 30,4 a 390, contro un h1 di 34 /
    30,7 / 26. Adesso 32 / 27,9 / 24: sempre sotto il titolo, e dentro la
    fascia 28-32 della scala di sezione.
*/
.pexp .shead h2 { font-size: clamp(1.5rem, 1.4vw + 0.85rem, 2rem); }

/* ==========================================================================
   29. LA GALLERIA SMETTE DI OCCUPARE TUTTO LO SCHERMO

   Misurato: il mosaico era alto 880 pixel su una finestra di 844 — il 104% dello
   schermo — e il TITOLO DELL'ANNUNCIO cadeva a 1098, cioe' sotto la piega. Si
   apriva la scheda di una casa e non si vedeva di quale casa si trattasse senza
   scorrere.

   La ragione e' aritmetica: la griglia ha tre colonne e tre righe quadrate, e tre
   righe alte quanto un terzo di 1312 fanno 880. Nessuno l'aveva scelto: era la
   conseguenza di `grid-auto-rows: 1fr` su una griglia larga.

   IL MOCKUP LA DISEGNA COME UNA FASCIA, non come un blocco: nella sua schermata la
   galleria sta in circa un terzo dell'altezza, con proporzione vicina a 2,6:1. Si
   fissa quella, e le righe si dividono l'altezza da sole — `grid-auto-rows: 1fr`
   continua a fare il suo lavoro, solo dentro un'altezza decisa invece che
   ereditata.

   Il risultato che conta non e' la proporzione: e' che il titolo torna sopra la
   piega, e con lui la riga dei dati e l'inizio della spalla.
   ========================================================================== */
/*
    `minmax(0, 1fr)` E NON `1fr`, ed e' tutta la differenza.

    `1fr` porta con se' un minimo automatico pari al contenuto: le righe non
    scendono sotto l'altezza della fotografia che contengono, quindi la proporzione
    dichiarata sul contenitore non vince mai. Misurato: con `aspect-ratio: 2.6/1` e
    `grid-auto-rows: 1fr` il mosaico restava a 880 pixel, identico a prima.

    Azzerando quel minimo le righe si lasciano stringere e si dividono l'altezza
    che la proporzione decide. Le fotografie non si schiacciano: sono gia'
    `object-fit: cover`, quindi si ritagliano.
*/
.pmosaic__grid {
    aspect-ratio: 2.6 / 1;
    grid-auto-rows: minmax(0, 1fr);
    grid-template-rows: repeat(3, minmax(0, 1fr));
}

.pmosaic__cell,
.pmosaic__tile { min-height: 0; }

/*
    Sotto i 60rem la colonna si stringe e una fascia 2,6:1 diventa una striscia
    alta centoventi pixel: li' la proporzione si allarga, perche' su uno schermo
    stretto la fotografia e' la sola cosa che puo' dire com'e' fatta la casa.
*/
@media (max-width: 59.99rem) {
    .pmosaic__grid { aspect-ratio: 1.9 / 1; }
}

/* Sul telefono il mosaico e' una striscia che scorre in orizzontale (§26.2): li'
   l'altezza la decide la striscia, non una proporzione. */
@media (max-width: 47.99rem) {
    .pmosaic__grid { aspect-ratio: auto; }
}

/* ==========================================================================
   30. LA SCHEDA DATI SI STRINGE SOTTO I 700

   Misurato a 480 e a 560: il blocco era alto 839 pixel su una finestra di 844 —
   il 99% dello schermo per nove righe di etichetta e valore. Ogni riga ne
   misurava 92: 22 di riempimento sopra, 22 sotto, un'icona da 38 e due righe di
   testo. E' lo stesso difetto del mosaico, nello stesso punto della pagina: un
   blocco che si prende uno schermo intero perche' nessuno lo ha misurato dopo che
   e' passato a una colonna.

   Su una sola colonna la riga non deve respirare come una scheda: e' una voce di
   elenco. Il riempimento scende a 14, l'icona a 26, e il blocco si dimezza.

   Sopra i 700 la scheda dati torna a due colonne e le righe hanno meta' della
   lunghezza: li' il respiro di prima e' giusto e non si tocca.
   ========================================================================== */
/*
    `.dossier .sp` E NON `.dossier__row`, e la ragione e' la specificita'.

    Una correzione precedente aveva gia' stretto la riga, ma solo sotto i 26.25rem:
    `@media (min-width: 26.25rem) .dossier .sp { padding: 1.375rem 1.5rem }` la
    rigonfiava da 421 in su, ed e' 0,2,0 — batte un `.dossier__row` nudo. Misurato:
    la mia prima versione cambiava la riga a 390 (74px) e non la toccava a 480 e
    560, che erano proprio le larghezze peggiori (839 pixel di blocco, il 99% dello
    schermo).
*/
@media (max-width: 43.74rem) {
    .dossier .sp {
        padding: 14px 16px;
        gap: 12px;
    }

    .dossier .sp > svg {
        width: 26px;
        height: 26px;
    }
}
