/*  The site's own stylesheet.

    Everything here used to be an inline <style> in base.html, which meant the
    palette, the type scale and every rule below travelled with every document —
    four and a half kilobytes, on every page, uncacheable because it was markup.
    As a file it is fetched once and then read from cache, and collectstatic
    gives it a content-hashed name so a change to it can never be served stale.

    Load order: after ibex-fonts.css and ibex-responsive.css, before
    ibex-light.css. That is the order the <link> tags declare and the order the
    cascade needs.

    Written to the standard the IBEX Capital project set. Not copied from it:
    the two firms are different companies with different palettes, and every
    colour below is IBEX SERVICES' own, measured rather than adopted.  */

/* ── the palette, and the only place it exists ──────────────────────────────
   These nine values were written out as hex literals in twelve files —
   blocks/_band.html, eight block templates, the 404 and this document's own
   <style>. That is not a palette, it is a habit: the difference between "the
   accent" and "#C9A96E" was a string to search for rather than a decision that
   could be revisited.

   Every ratio below was measured against the band the colour is used on, by
   scripts/check_contrast.py, which reads this file rather than a table
   somebody retyped. WCAG 2.2 AA asks 4.5:1 of body text and 3:1 of text at
   24px or above. Nothing here is below 4.5:1 on any ground it is used on.

   WHAT THIS PALETTE DOES NOT HAVE, and why the Capital one does. That project
   carries --acc-lg, a second value of the accent for type set large, because
   its gold is a bright 8.1:1 metal that shouts at forty pixels. This accent is
   a soft tan and there is no size at which it shouts, so a second value would
   be a ramp nobody can see. It does have the other tier Capital added —
   --ink-045, the step below muted — because the footer's address and the
   regulatory disclosure were already using it, as a literal, in two files.  */
:root{
  --serif:"Playfair Display", Georgia, serif;
  --sans:"Archivo", system-ui, sans-serif;

  --ink-900:#0D0D0D;   /* the dark band */
  --ink-800:#171614;   /* the dark band, recessed — the closing call to action */
  --ink-100:#F0EDE8;   /* type on dark                            16.6:1 */
  --ink-060:#A79F96;   /* muted type on dark                       7.4:1 */
  --ink-045:#8C857D;   /* the address, the disclosure, the tab      5.3:1 */

  --paper-050:#FBFAF8; /* the light band */
  --paper-100:#F0ECE4; /* the warm band */
  --paper-900:#1A1817; /* type on light                           17.0:1 */
  --paper-500:#635C53; /* muted type on light         6.3:1 · warm 5.6:1 */
  --paper-045:#6E6760; /* the same step, on paper     5.4:1 · warm 4.8:1 */

  --gold:#C9A96E;      /* the accent on dark: marks, links, focus  8.7:1 */
  --gold-deep:#7E6128; /* the same metal on paper     5.6:1 · warm 4.9:1 */
  /* The lamp, as components, because rgba() needs them separately. This is
     --gold opened up and desaturated: a glow carries its hue over a large soft
     area, where the value that reads as metal in a hairline reads as a yellow
     spotlight. */
  --gold-lamp:214,190,144;

  --color-accent:var(--gold);
}

/* The vertical scale, and the only four steps anything inside a band may use.
   Eleven values were in circulation for four jobs — 8, 10, 12, 14, 16, 18, 20,
   22, 24, 26, 30 — and the difference between 20 and 22 is not a decision
   anyone makes, it is a decision nobody made. Read down a page it registers as
   almost-aligned, which is worse than either alignment or contrast. */
:root{
  --s-tight:8px;    /* a label to the thing it labels */
  --s-inner:14px;   /* within one element: kicker to heading, figure to note */
  --s-between:18px; /* element to element: heading to prose */
  --s-group:32px;   /* group to group inside one band */
}

/* The interlinear scale, which the one above always had and this never did.
   Two tokens, for the two roles where a reader's eye crosses many lines and the
   rhythm has to be the same one every time.

   Display sizes are deliberately NOT here. Every line height on a heading is an
   optical decision about a particular size — a 64px headline closes to 1.06, a
   19px standfirst opens to 1.72 — and a token that averaged them would replace
   a dozen judgements with one compromise. A scale is for what repeats; the
   display line is set once, by eye, per size. */
:root{
  --lh-prose:1.75;  /* running text, 14–19px */
  --lh-note:1.7;    /* captions, credits, small print, 11–13px */
}

/* Motion, and the only three values anything that answers the reader moves by.
   There were five in circulation — .25s, .3s, .4s, .42s and 1s, on four
   different curves — and none of them was chosen against the others: the
   header took .4s to change colour, longer than the button under it took to
   fill. A control that answers in 400ms reads as one that is thinking.

   --ease-out starts fast and settles, which is what a reply should feel like;
   the stock `ease-out` is too weak to read as a decision. Colour changes keep
   plain `ease`, because nothing moves and there is no arrival to shape.

   The reduced-motion branch in ibex-responsive.css takes every duration to
   zero; it never takes away a state, only the time spent reaching it. */
:root{
  --ease-out:cubic-bezier(.23,1,.32,1);
  --t-colour:180ms;  /* hover, and the header turning over a band */
  --t-press:140ms;   /* a control answering a press */
}

/* The header's height, once, because three things have to agree on it: the
   header itself, the phone's menu sheet that opens directly beneath it, and the
   anchor offset that stops a deep link landing under it. It was a literal in
   all three — 88 in header.html, 89 twice in the sheet's rule — and 92 in
   ibex-chrome.js, which now measures the header instead of trusting a number.
   Sixty-four on a phone: the header follows the reader down the page, and a
   permanent 88px is eleven per cent of a 812px screen spent on chrome. */
:root{--hdr-h:88px}
@media (max-width:640px){:root{--hdr-h:64px}}

*{box-sizing:border-box}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%;scroll-padding-top:calc(var(--hdr-h) + 16px)}
/* LA TESTATA NON RESTAVA IN CIMA, e la causa era una parola in questa riga.
   Il `body` portava `overflow-x:hidden`, che vince sul `clip` di
   ibex-responsive.css perche' questo foglio si carica dopo. `hidden` su un
   asse porta l'altro ad `auto`: il body diventava un contenitore di
   scorrimento, cioe' l'antenato contro cui `position:sticky` si misura — e il
   body non scorre mai, scorre la finestra. Misurato a 1440 il 10.10.2026: con
   la pagina scesa di 3000 pixel la testata stava a -3000, fuori dallo schermo,
   mentre ibex-chrome.js continuava a ribaltarne i colori. Sul telefono il
   menu, che e' figlio della testata, se ne andava con lei. Dal 22.08.2026.
   Il `clip` di ibex-responsive.css fa lo stesso lavoro senza creare un
   contenitore; home/tests/test_layout_css.py impedisce che torni. */
body{margin:0;background:var(--ink-900);color:var(--ink-100);font-family:"Archivo",system-ui,sans-serif}
a{color:inherit;text-decoration:none}

/* ---- the details that are noticed without being looked at --------------- */

/* Selection in the accent at low strength, and the text stays legible through
   it. The browser default is a blue that belongs to no palette. */
::selection{background:rgba(var(--gold-lamp),0.28);color:inherit}

/* A focus ring that sits far enough out to be read as attention rather than as
   a border, and follows the shape it is on rather than boxing it.

   IL COLORE NON PUO' ESSERE UNO SOLO, e per un anno lo e' stato: --gold. WCAG
   2.2 SC 1.4.11 «Non-text Contrast» chiede 3:1 di un indicatore di fuoco contro
   il fondo su cui si posa, e il #C9A96E e' scelto per le bande scure, dove
   misura 8.68:1. Sulle bande chiare misura 2.15:1.

   Misurato sul sito servito il 02.09.2026, spazzando i quarantotto indirizzi
   del sitemap: 127 elementi raggiungibili da tastiera stanno dentro una banda
   chiara — 103 collegamenti, e quattro volte i nove comandi del modulo di
   contatto. Chi compila il modulo della societa' con la tastiera non vedeva
   quale campo avesse il fuoco. Alla testata succedeva lo stesso ogni volta che
   passava sopra una banda chiara.

   PERCHE' IL CONTROLLO DEL DEPLOY NON LO VEDEVA. scripts/check_contrast.py
   misura coppie testo/fondo prese dalla tavolozza e dai token della testata;
   il colore di un outline non e' ne' l'uno ne' l'altro, e 1.4.11 non e' 1.4.3.
   home/tests/test_accessibility.py rifa' il conto su ogni fondo del sito.

   NESSUN COLORE NUOVO. Ogni banda dichiara gia' il proprio accento in --acc
   (blocks/_band.html: var(--gold) sulle scure, var(--gold-deep) sulle chiare)
   e la testata dichiara gia' il suo in --chrome-acc, che [data-over="light"]
   ribalta insieme al resto della chrome. L'anello prende quello. Dopo: 5.55:1
   sulla banda chiara e sulla testata ribaltata, 8.68:1 dove era gia' giusto.

   IL CASSETTO DEL TELEFONO E' L'ECCEZIONE, ed e' il motivo per cui la riga
   della testata non basta da sola: [data-mobnav] sta dentro <header> ma non si
   ribalta — e' una lastra sul fondo scuro della tavolozza ovunque si apra
   (si veda la sua regola piu' sotto). Con il solo --chrome-acc avrebbe preso
   #7E6128 sul #0D0D0D, cioe' 3.36:1: sopra la soglia, e un terzo di quello che
   aveva. Il difetto che si introduce riparando l'altro.  */
:root{--focus:var(--gold)}
[data-band]{--focus:var(--acc)}
[data-header]{--focus:var(--chrome-acc)}
[data-mobnav]{--focus:var(--gold)}
:focus-visible{outline:2px solid var(--focus,var(--gold));outline-offset:3px;border-radius:1px}

.skip-link{position:absolute;left:-9999px;top:0;z-index:200;background:var(--gold);color:var(--ink-900);padding:12px 20px;font-size:13px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}
.skip-link:focus{left:0}

/* ---- the type scale -----------------------------------------------------
   Headings tighten as they grow and prose does not: a serif at fifty pixels
   set at the tracking of a paragraph reads as loose, and the same tracking on a
   paragraph reads as nothing at all. Declared once here rather than inline on
   every heading, so the relationship between the sizes is a rule instead of
   forty separate decisions. */
h1,h2,h3,h4{margin:0;font-weight:400;text-wrap:balance;overflow-wrap:break-word}
h1{letter-spacing:-0.028em}
h2{letter-spacing:-0.024em}
h3{letter-spacing:-0.016em}
p{margin:0}

/* German builds one word where English builds three, and a heading is the one
   place the column is narrow and the type is large. «Geldwäschereibekämpfung»
   is 24 characters that cannot be broken anywhere good, and on the German
   legal notice it is a sub-heading inside a 68-character measure. Hyphenation
   is the fix rather than break-word, because the browser knows German breaks
   at Geldwäscherei-bekämpfung and break-word would cut it wherever the line ran
   out. It needs the language, which <html lang> already declares. French gets
   it for the same reason; English and Italian do not, both because they need it
   far less and because hyphenation in a display serif is a decision, not a
   default. */
:lang(de) h1,:lang(de) h2,:lang(de) h3,:lang(de) h4,
:lang(fr) h1,:lang(fr) h2,:lang(fr) h3,:lang(fr) h4{hyphens:auto}

/* A serif at display size is drawn for print, where it is not asked to sit on a
   black ground. Half a hairline of negative weight takes back the thickening
   that a light-on-dark rendering adds. */
h1,h2{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}

/* Numbers align in columns wherever they are set, without asking. On a page of
   dates, article counts and register numbers, proportional figures wobble.

   `dt` si e' aggiunto dopo averlo misurato. In blocks/definitions.html il
   TERMINE e' la cifra — «≈42%», «≈23%», «≈11%», incolonnate una sotto l'altra —
   e la descrizione e' la prosa. La regola dava le figure tabulari al `dd`, cioe'
   alla prosa, e le negava al `dt`, cioe' all'unica colonna di numeri della
   pagina: esattamente al contrario. Il `dd` resta, perche' altrove porta cifre
   davvero, e su un testo senza numeri la dichiarazione non ha effetto. */
.tnum,dt,dd,time,[data-figure]{font-variant-numeric:tabular-nums}

/* The heavy tracking on the design's small uppercase labels leaves a gap after
   the final letter that reads as a misalignment against anything under them.
   Pulled back by exactly the tracking that caused it. */
p[style*="text-transform:uppercase"]{margin-right:-0.24em}

/* ---- rich text ----------------------------------------------------------
   The one place the markup is written by an editor rather than by a template,
   so it cannot carry inline styles. The static site set a margin on every
   paragraph by hand; here the rule does it once. */
.rich-text p+p{margin-top:var(--s-between)}
.rich-text ul,.rich-text ol{margin:var(--s-between) 0 0;padding-left:22px}
.rich-text li+li{margin-top:var(--s-tight)}
.rich-text li{line-height:var(--lh-prose)}
/* Strategic bold, which is the only kind worth having: the phrase a reader who
   is skimming must not miss. Set at 600 and in the band's foreground rather
   than at 700 in an inherited grey — the weight alone is the emphasis, and
   prose that turns a shade darker to make its point is shouting. */
.rich-text b,.rich-text strong{font-weight:600;color:var(--fg)}
/* a[href] e non a. Quando il bersaglio di un collegamento interno smette di
   essere pubblicato, home/wagtail_hooks.py restituisce <a> senza href — «a
   sentence that referred to a page which is no longer published should read as
   a sentence». Con il selettore largo il foglio di stile lo dipingeva lo
   stesso: accento, sottolineatura, e l'animazione qui sotto. Sembrava un
   collegamento in tutto tranne che nel funzionare. */
.rich-text a[href]{color:var(--acc);border-bottom:1px solid var(--rl2)}
/* An em inside prose is the legal register's own device — «fiduciario
   commercialista», «albo dei fiduciari» — and it is a Latin or Italian term of
   art, not emphasis. It keeps the italic and takes nothing else. */
.rich-text em{font-style:italic}

/* A hairline where two bands of the same colour meet. Without it the join is
   invisible and the sections read as one undifferentiated column of air. */
main > div > section + section,
main > section + section{border-top:1px solid var(--rl2)}
main > div > section[data-band="dark"] + section[data-band="dark"],
main > section[data-band="dark"] + section[data-band="dark"]{border-top-color:rgba(240,237,232,0.09)}

/* ---- i ritratti ----------------------------------------------------------
   Rimessa il 28 agosto 2026. `people.html` porta `class="grayscale"` fin dalla
   riscrittura, il vecchio sito la definiva esattamente così, e questa
   riscrittura non l'ha portata: la classe stava nel markup e non stilava
   niente. Un attributo class senza regola non dà nessun errore — non in
   pagina, non nel deploy, non nei test — e l'unico modo di accorgersene è
   guardare la pagina sapendo che cosa aspettarsi.

   Che cosa faceva, misurato sulle tre foto vere: i tre ritratti vengono da tre
   sedute diverse e a colori non stanno insieme — capelli ramati, una camicetta
   bianca, e due neri di fondo che non sono lo stesso nero (uno neutro, uno
   caldo di 4 punti su R-B). Desaturati diventano una serie. Non chiude la
   differenza fra lo sfondo grigio di uno e il nero degli altri due, che è di
   luminanza e non di colore: quella è una domanda per il fotografo. */
.grayscale{filter:grayscale(1) contrast(1.08)}

/* La vignettatura, chiesta il 28 agosto 2026. Non ripara la differenza fra i
   fondali — la accorcia. Luminanza media della striscia alta, misurata sulle
   renditions vere: 106 / 38 / 22 senza velo, 62 / 27 / 17 con. La distanza fra
   il più chiaro e il più scuro passa da 84 a 45.

   PERCHÉ NON DI PIÙ. Una taratura che chiude fino a 37 esiste, ed è quella che
   avevo mostrato in anteprima — ma era disegnata con un'ellisse sfocata, che è
   un operatore che un browser non ha. Riscritta come radial-gradient e misurata
   contro il riquadro del viso di ciascuna delle tre foto, quella taratura
   scurisce un viso (alfa 0,076). Il vincolo è che i visi non si toccano: la
   linea degli occhi di Benedetti sta al 32% dell'altezza, cioè proprio dove
   servirebbe scurire. Fra le tarature che lo rispettano, questa è la più
   efficace: alfa media sul viso 0,047 su Camponovo e meno sugli altri due.

   L'ordine conta e non è quello che sembra: `filter` sta sul contenitore e
   ::after è un suo figlio, quindi il browser compone immagine + velo e POI
   filtra il risultato. Con contrast() attorno a 0,5 le due sequenze danno
   numeri diversi; i 45 qui sopra sono misurati nell'ordine del browser.

   `:has(img)` NON è ornamentale. Lo stesso contenitore ospita il monogramma,
   quando una persona non ha ritratto: è una targa piatta sulla tinta della
   banda, e scurirle gli angoli non legge come un'intenzione, legge come una
   macchia. Il velo vale solo dove c'è una fotografia. */
.grayscale:has(img)::after{
  content:"";
  position:absolute;
  inset:0;
  pointer-events:none;
  background:radial-gradient(ellipse 78% 68% at 50% 42%,
             rgba(10,10,10,0) 32%,
             rgba(10,10,10,.42) 64%,
             rgba(10,10,10,.94) 100%);
}

/* ---- motion, meant to be felt ------------------------------------------- */
@media (prefers-reduced-motion: no-preference){
  /* Body links draw their rule from the left over a third of a second. The
     instant appearance of an underline is the single commonest tell of a
     template; a line that is drawn was decided on.

     DUE STRATI, NON UNO — ESC-30, 05.09.2026. Questo ramo azzerava il
     `border-bottom` della riga 206 e lasciava il collegamento senza nessuna
     linea a riposo. `--acc` sta a 1,14:1 da `--mut`, cioe' dal testo che lo
     circonda: il colore diventava l'unica differenza fra un collegamento e la
     frase in cui sta, che e' la SC 1.4.1, livello A. E il ramo conforme
     risultava quello di `prefers-reduced-motion: reduce` — l'indizio era
     finito dentro la clausola che riguarda una minoranza.

     Nessun colore puo' risolverla: perche' `--acc` stacchi 3:1 dal testo
     dovrebbe schiarirsi fino a 2,11:1 contro il fondo, e allora perde la
     1.4.3, oppure annerire fino a non essere piu' un accento. La tavolozza non
     ha spazio, quindi serve un indizio che non sia il colore.

     Lo strato di sotto e' quel filetto, a tutta larghezza, in `--rl2`: lo
     stesso identico aspetto che la riga 206 gia' serve a chi chiede meno
     movimento. Lo strato di sopra e' la linea d'accento che continua a
     disegnarsi da zero, sulla STESSA riga di pixel — stesso
     `background-position`, stessa altezza. Per questo non si usa il bordo:
     il bordo sta sotto la casella di riempimento e darebbe due filetti
     affiancati al passaggio, oppure uno scatto di un pixel. Cosi' invece il
     gesto e' identico a prima e il collegamento e' riconoscibile fermo. */
  .rich-text a[href]{
    background-image:linear-gradient(currentColor,currentColor),
                     linear-gradient(var(--rl2),var(--rl2));
    background-repeat:no-repeat;
    background-position:0 100%,0 100%;
    background-size:0 1px,100% 1px;
    border-bottom:0;
    transition:background-size .3s var(--ease-out);
  }
  .rich-text a[href]:hover,.rich-text a[href]:focus-visible{background-size:100% 1px,100% 1px}

  /* 700ms, not the second it was. The curve spends most of its time arriving,
     so a full second read as text that had not finished loading. */
  html.ibex-js [data-reveal]{opacity:0;transform:translateY(16px)}
  html.ibex-js [data-reveal].is-in{opacity:1;transform:none;transition:opacity .7s var(--ease-out),transform .7s var(--ease-out)}
}

/* ---- where one band meets the next --------------------------------------
   Each band draws its own contours, so a line that runs into the boundary is
   cut there — and a sliced contour is the one thing on this background that
   reads as a seam. The texture fades out over the last seven per cent of each
   band instead. It is a mask on the layer, not a gradient over the content, so
   nothing is painted on top of the text and the band colour stays exactly what
   the palette says. */
ibex-atmosphere{
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 7%,#000 93%,transparent 100%);
}
/* The hero opens the page: there is nothing above it to dissolve into, and
   fading its top edge would leave the first screen emptier than it is. */
main > div > section:first-child ibex-atmosphere,
main > section:first-child ibex-atmosphere,
main > header:first-child ibex-atmosphere{
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 93%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 93%,transparent 100%);
}

/* ---- la fotografia nella hero -------------------------------------------
   Lo stambecco del Piz Nair sulla home, in due forme.

   Sopra 900 prende quasi meta' della larghezza e tre quarti dell'altezza: un
   pannello alto, ancorato a destra, che si dissolve verso il testo invece di
   finire con un bordo. Non c'era
   spazio per tanto finche' i due pulsanti stavano nella colonna destra della
   griglia — a quel punto il pannello doveva chiudersi prima di loro e stava
   nel 36% della larghezza. La griglia della home passa a colonna sola e la
   destra si libera: e' la riga `[data-heropic] [data-herogrid]` piu' sotto, ed
   e' il perno di tutta questa composizione.

   Sotto 900 quel vuoto non c'e' piu' e la fotografia diventa una fascia in
   cima alla sezione, prima del testo. In cima e non in fondo: il motivo per
   cui questa immagine esiste e' che caricando il sito non se ne vedeva
   nessuna, e una fotografia in fondo alla hero sarebbe di nuovo sotto la
   piega su un telefono. 900 e non un numero scelto qui: e' dove commutano il
   menu, la griglia della hero e ogni altra coppia di colonne del sito, e un
   secondo punto di rottura vicino al primo si nota.

   IL RITAGLIO NON E' NEL CSS. object-position sposta una finestra dentro un
   file gia' tagliato; i due file li taglia scripts/prepare_hero_photo.py, uno
   per forma. Un ritaglio solo, girato fra un pannello 0.81:1 e una fascia
   1.8:1, taglia le corna in una delle due — che e' il difetto gia' pagato una
   volta sulla banda fotografica.

   I COLORI NON SONO QUI. La didascalia usa --fg e --mut della banda, come
   ogni altro testo del sito, ed e' quello che la fa stampare: il foglio di
   stampa ribalta quei due token in inchiostro e la didascalia segue. Il velo
   e' l'unica cosa che non puo' seguire, perche' un gradiente non e' un token,
   e infatti porta data-veil e la stampa lo spegne. */
[data-heroland]{position:relative;z-index:1}
/*  68vw, e la ragione e' aritmetica. Un'altezza in vw tiene un rapporto
    COSTANTE su tutta la fascia in cui vale — qui 1.47:1 contro l'1.55:1 del
    ritaglio, cioe' la fascia e' appena piu' stretta della fotografia e non ne
    taglia NIENTE in altezza a nessuna larghezza. Con l'altezza fissa che
    c'era prima, a 768 la finestra scendeva al 56% e la banda diventava mezzo
    cielo vuoto con l'animale in un angolo: simulato ritaglio per ritaglio,
    non guardato, perche' e' un difetto della cornice e uno scatto a schermo
    intero lo attraversa senza vederlo.  */
[data-heropanel]{position:relative;overflow:hidden;height:clamp(230px,68vw,540px)}
[data-heropanel] picture{display:block;width:100%;height:100%}
[data-heropanel] img{
  display:block;width:100%;height:100%;object-fit:cover;object-position:50% 22%;
  /* La stessa desaturazione della banda fotografica, un filo meno scura:
     qui sopra ci va del testo solo sul bordo che si dissolve, non sopra la
     fotografia intera. */
  filter:saturate(.22) contrast(1.14) brightness(.82);
}
[data-heropanel] [data-veil]{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to bottom,rgba(13,13,13,.55) 0,rgba(13,13,13,0) 24%,rgba(13,13,13,0) 56%,rgba(13,13,13,.97) 100%);
}
/*  --ink-045 E NON --mut, PER TUTTE E DUE LE RIGHE, ed e' il secondo passo di
    una correzione fatta in due. La didascalia stava a --fg, cioe' al colore
    pieno: portata a --mut era ancora troppo presente, e chiesto di attenuarla
    ancora si scopre che il difetto non era il valore ma il fatto che questo
    blocco stesse nella scala del TESTO DELLA PAGINA. Non lo e': accompagna una
    fotografia, e --ink-045 e' il gradino che la tavolozza tiene esattamente per
    questo — «the address, the disclosure, the tab», 5.34:1 sul fondo scuro.

    Scendono INSIEME. Attenuare la sola didascalia lascerebbe il credito a 7.4
    contro i 5.3 di lei, cioe' rimetterebbe la riga piu' chiara dell'angolo
    accanto alla fotografia: lo stesso difetto di prima, spostato di una riga.

    5.34:1 contro il 4.5 che l'AA chiede a 10.5 e 12.5px. Il credito resta un
    adempimento CC BY-SA e resta leggibile: e' lo stesso colore con cui il
    footer compone l'indirizzo della societa' a 13px, e ibex-print.css lo
    porta gia' su 659 caratteri di testo su nero.

    E resta un token perche' ibex-responsive.css lo ribalta in #3A352F sulla
    carta bianca. Un colore scritto a mano qui uscirebbe chiaro su bianco.  */
[data-herocredit]{
  margin:0;padding:clamp(10px,1.2vw,14px) clamp(20px,4vw,64px) 0;
  font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;
  line-height:var(--lh-note,1.6);color:var(--ink-045);
}
/*  Lo stesso colore del credito, e la ragione sta nel commento qui sopra.

    IL FONDO E' L'INCHIOSTRO DELLA BANDA, E NON PER MODO DI DIRE. Misurato
    sulle due larghezze invece che dedotto dal gradiente: a 1400 il pannello
    finisce a y=935 e il blocco del credito comincia a y=935; a 390 finiscono
    e cominciano a y=354. Stacco zero, intersezione nessuna, in tutti e due i
    rami. Quindi qui sotto non c'e' mai fotografia, e un token misurato contro
    la banda e' lo strumento giusto — 4.97:1 secondo check_contrast.py, che il
    fondo se lo compone da solo con la luce sopra.

    Scritto cosi' di proposito. Il ragionamento facile e' «tanto il velo ha
    gia' portato l'immagine al nero», ma il velo si compone NEL PUNTO in cui
    sta l'elemento e non dove finisce la sfumatura: sul sito gemello quel
    ragionamento ha coperto un 4.26:1 vero. Qui la garanzia non e' il velo,
    e' che i due riquadri non si toccano.

    Resta piu' grande del credito — 12.5 contro 10.5 — e in tondo minuscolo
    invece che maiuscolo spaziato: le due righe si distinguono per quello che
    le distingue davvero, non perche' una e' piu' accesa dell'altra.  */
[data-herocap]{
  display:block;margin-bottom:5px;
  font-size:12.5px;letter-spacing:0;text-transform:none;color:var(--ink-045);
}
[data-herocredit] a{color:inherit;text-decoration:underline;text-underline-offset:3px}

@media (min-width:900px){
  /* Il pannello sanguina fino al bordo destro della sezione, non del
     contenitore: fermarlo sul contenitore lascerebbe una colonna di fondo
     scuro alla sua destra su ogni schermo sopra i 1800.

     bottom:0 NON E' DECORAZIONE. Senza, il riquadro ha altezza automatica, e
     una percentuale di altezza contro un contenitore ad altezza automatica non
     risolve: misurato a 900, `min(62%,640px)` dava 206.77px — ne' il 62% della
     sezione ne' i 640 del limite, ma il residuo di una dipendenza circolare
     fra il figlio e il padre. Con top e bottom fissati l'altezza del padre e'
     definita e il 52% e' il 52%.

     pointer-events: il riquadro copre il terzo destro di tutta la sezione,
     dove piu' in basso stanno i due pulsanti. Stanno sopra per z-index e i
     clic gia' li raggiungono; questo lo rende vero per costruzione invece che
     per ordine di dipintura. Il link della licenza se li riprende: e' l'unica
     cosa cliccabile qui dentro, ed e' anche l'adempimento. */
  [data-heroland]{position:absolute;top:0;right:0;bottom:0;z-index:0;width:min(48%,720px);pointer-events:none}
  [data-herocredit] a{pointer-events:auto}
  /*  LA COLONNA DESTRA DELLA GRIGLIA VIENE CHIUSA, ed e' questa riga che
      lascia crescere la fotografia. La hero manda in griglia il sommario e i
      due pulsanti, e sopra i 900 i pulsanti stanno a destra: cioe' sotto il
      pannello. Finche' ci stanno, l'altezza della fotografia e' vincolata a
      chiudersi prima di loro — misurato, il 48% della sezione, oltre il quale
      la didascalia entrava nei pulsanti. A colonna sola sommario e pulsanti si
      impilano a sinistra, la destra si libera per intero e il pannello passa
      dal 48% al 74% di altezza e dal 36% al 48% di larghezza: poco piu' del
      doppio dell'area, 2.1 volte, uguale a ogni larghezza perche' i due
      fattori sono entrambi proporzioni.

      !important, e due attributi invece di uno, perche' la regola che apre
      la seconda colonna — «the grids», piu' sotto — e' anch'essa !important
      (deve battere il valore di riserva nell'attributo style). Fra due
      !important vince la specificita': (0,2,0) contro (0,1,0), in qualunque
      ordine stiano nel foglio. Fino al 10.10.2026 la seconda colonna la
      scriveva ibex-layout.js come stile in linea; la ragione per non toccare
      il motore resta la stessa — questa e' una decisione di composizione di
      UNA pagina, e la regola generale impagina TUTTE le bande del sito.  */
  [data-heropic] [data-herogrid]{grid-template-columns:minmax(0,1fr) !important}
  /* 74%. Sotto il pannello ci va ancora la didascalia, e sotto di lei ormai
     non c'e' piu' niente a destra — resta solo da non arrivare in fondo alla
     sezione, dove la banda finisce e comincia quella dopo. */
  [data-heropanel]{
    height:74%;
    /* Non c'e' un bordo, c'e' una fine. La dissolvenza comincia larga —
       .42 gia' al 18% — perche' l'animale occupa i due terzi sinistri del
       ritaglio e una maschera piu' stretta se ne mangerebbe la groppa. */
    -webkit-mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.42) 18%,rgba(0,0,0,.90) 46%,#000 70%);
    mask-image:linear-gradient(to right,transparent 0,rgba(0,0,0,.42) 18%,rgba(0,0,0,.90) 46%,#000 70%);
  }
  [data-heropanel] img{object-position:50% 50%}
  /* Allineata alla fotografia e non al contenitore: e' la didascalia di
     quella, non della pagina. */
  [data-herocredit]{padding:14px 26px 0 clamp(20px,3vw,40px);text-align:right}
  /*  IL TITOLO SI FERMA PRIMA DEL PANNELLO, e questa riga e' una correzione,
      non una rifinitura. 19ch e' scritto in linea nel template ed e' una
      misura tipografica: conta i caratteri, non lo spazio rimasto. In tedesco
      «Um die Schweiz kümmern» ci sta dentro e a 900 arriva a 652 pixel, dove
      il pannello comincia a 570 — misurato, si sovrapponevano davvero, e la
      didascalia della fotografia passava attraverso la terza riga del titolo.
      Il 50% e' la larghezza oltre la quale il testo entrerebbe nel pannello a
      ogni larghezza fra 900 e 1920, ora che il pannello e' largo il 48%. In
      italiano non cambia niente: le righe sono gia' piu' corte del limite. In
      tedesco aggiunge una riga, che e' il prezzo, e va pagato qui e non
      lasciato al caso della lingua.
      !important perche' il valore che scavalca sta in un attributo style.  */
  [data-heropic] h1{max-width:min(19ch,50%) !important}
  /*  E lo stesso per il sommario, che finora non aveva mai raggiunto il
      pannello perche' il pannello era stretto. A 900 il pannello comincia a
      463 e il limite ferma il paragrafo a 445; senza, le 58 battute lo
      porterebbero sopra la meta' opaca della fotografia. 58ch resta il valore
      su ogni altra pagina — qui e' solo il minore dei due.  */
  [data-heropic] [data-herogrid] > p{max-width:min(58ch,50%) !important}
  /*  E ANCHE I PULSANTI, che non sono testo e non avevano un limite. Chiudere
      la colonna destra li ha resi larghi quanto tutta la griglia: misurato a
      900, il loro contenitore andava da 36 a 854 e il secondo pulsante
      finiva a 587, dentro la didascalia che comincia a 463. Con il limite si
      impilano quando non ci stanno affiancati, che e' quello che il flex-wrap
      gia' sa fare — mancava solo qualcosa contro cui misurarsi.  */
  [data-heropic] [data-herogrid] > div{max-width:50%}
}

/* ── the chrome, and the band under it ─────────────────────────────────────
   The header lies on whatever band is passing beneath it, and inverts. Both
   states are here, as two sets of the same six tokens; ibex-chrome.js does
   nothing but put data-over="light" on <html> when the band under the probe
   line is a light one.

   This is the fix for a defect the palette audit found and that nothing else
   could have. The script used to write these colours itself, as literals, onto
   five selectors — and [data-burger], [data-mobbtn] and [data-navlink] were
   never in the markup, while --lang-on and --lang-off were set on the header
   and read by nobody. Over a light band the header background went light and
   the navigation did not: #A79F96 links at 2.50:1 and a #F0EDE8 active link at
   1.12:1, which is white on white. It looked correct from every dark band, and
   the dark bands are where anybody testing it would have started.

   Every value below is measured by scripts/check_contrast.py against the
   ground it sits on, in both states, and the deploy stops if one drops under
   WCAG AA. That is the whole reason the colours had to come out of the script:
   a stylesheet can be read by arithmetic and a sequence of assignments cannot.

   The DARK values are the ones the site has always had. The LIGHT ones are new,
   because there were none — three of them had to be chosen, and each is the
   band's own equivalent from the palette rather than a fresh colour. */
:root{
  --chrome-bg:rgba(13,13,13,0.90);
  --chrome-rule:rgba(240,237,232,0.14);
  --chrome-fg:#F0EDE8;                     /* --ink-100, active link   16.6:1 */
  --chrome-mut:#A79F96;                    /* --ink-060, other links    7.4:1 */
  --chrome-acc:#C9A96E;                    /* --gold, CTA and current   8.7:1 */
  --chrome-off:#8C857D;                    /* --ink-045, other langs    5.3:1 */
  --chrome-edge:rgba(240,237,232,0.24);    /* the burger's box */
  --chrome-on-acc:#0D0D0D;                 /* --ink-900, on the CTA filled 8.7:1 */
}
[data-over="light"]{
  --chrome-bg:rgba(251,250,248,0.92);
  --chrome-rule:rgba(26,24,23,0.14);
  --chrome-fg:#1A1817;                     /* --paper-900              17.0:1 */
  --chrome-mut:#635C53;                    /* --paper-500               6.3:1 */
  --chrome-acc:#7E6128;                    /* --gold-deep               5.6:1 */
  --chrome-off:#6E6760;                    /* --paper-045               5.3:1 */
  --chrome-edge:rgba(26,24,23,0.22);
  --chrome-on-acc:#FBFAF8;                 /* --paper-050, on the CTA filled 5.6:1 */
}

[data-header]{background:var(--chrome-bg);border-bottom:1px solid var(--chrome-rule);transition:background-color var(--t-colour) ease,border-color var(--t-colour) ease}

[data-desknav]{display:none;align-items:center;gap:clamp(12px,1.35vw,22px)}
[data-navlink]{font-size:13px;font-weight:500;letter-spacing:.04em;color:var(--chrome-mut);padding:4px 0;border-bottom:1px solid transparent;transition:color var(--t-colour) ease,border-color var(--t-colour) ease}
[data-navlink][data-active="1"]{color:var(--chrome-fg);border-bottom-color:var(--chrome-acc)}

[data-desklang]{display:none;align-items:center;gap:1px}
[data-lang-btn]{padding:6px 7px;font-size:11px;font-weight:600;letter-spacing:.14em;color:var(--chrome-off);transition:color var(--t-colour) ease}
/* The current language is underlined as well as gold. The colour alone was
   1.63:1 against the codes beside it on the dark header and 1.04:1 on the
   light one — a difference of hue, which a reader who does not see hue does
   not get (SC 1.4.1). The line is the navigation's own
   sign for «here», drawn in the padding, so nothing moves. */
[data-lang-btn][aria-current]{color:var(--chrome-acc);text-decoration:underline 1px;text-underline-offset:5px}

[data-headercta]{display:none;border:1px solid var(--chrome-acc);color:var(--chrome-acc);padding:11px 18px;font-size:12px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;transition:background-color var(--t-colour) ease,color var(--t-colour) ease,border-color var(--t-colour) ease,transform var(--t-press) var(--ease-out)}

[data-mobmenu]{position:relative}
[data-mobmenu] summary::-webkit-details-marker{display:none}
[data-mobbtn]{display:flex;flex-direction:column;justify-content:center;gap:5px;width:44px;height:44px;border:1px solid var(--chrome-edge);cursor:pointer;padding:0 11px;list-style:none;-webkit-tap-highlight-color:transparent;transition:border-color var(--t-colour) ease}
[data-burger]{display:block;height:1px;background:var(--chrome-fg);transition:transform .2s var(--ease-out),opacity .12s ease,background-color var(--t-colour) ease}
/* The three lines become a cross, so the control that opened the sheet says
   how to close it. Six pixels is the distance from each outer line to the
   middle one — a gap of five and a line of one — so the two meet exactly. */
[data-mobmenu][open] [data-burger]:nth-child(1){transform:translateY(6px) rotate(45deg)}
[data-mobmenu][open] [data-burger]:nth-child(2){opacity:0}
[data-mobmenu][open] [data-burger]:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

/* The mobile panel is a sheet over the whole page rather than a strip lying on
   one band, so it does not invert: it is the palette's dark, wherever it
   opens. ibex-chrome.js takes the header dark with it while it is open, so
   the two read as one surface rather than a light bar over a dark sheet.

   IT FILLS THE SCREEN. It used to stop where its links did, 531 pixels down a
   812-pixel phone, and the page went on underneath — still scrollable, with
   nothing to say the menu was a separate place. The header's own rule is the
   line between them; the sheet does not draw a second one.

   `top` is measured from the header and not from the window: backdrop-filter
   makes the header the containing block of anything fixed inside it. */
[data-mobnav]{position:fixed;left:0;right:0;top:calc(var(--hdr-h) + 1px);z-index:99;background:var(--ink-900);height:calc(100vh - var(--hdr-h) - 1px);height:calc(100dvh - var(--hdr-h) - 1px);overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;padding:8px clamp(20px,4vw,64px) calc(28px + env(safe-area-inset-bottom,0px))}
[data-mobnav] > a{padding:15px 0;border-bottom:1px solid rgba(240,237,232,0.14);font-family:var(--serif);font-size:21px;color:var(--ink-100);-webkit-tap-highlight-color:transparent;transition:color var(--t-colour) ease,border-color var(--t-colour) ease}
/* Where the reader is, said the way the desktop navigation says it: the
   accent, and the line under it. aria-current carries it to a screen reader. */
[data-mobnav] > a[aria-current="page"]{color:var(--gold);border-bottom-color:var(--gold)}
[data-mobnav] [data-mobcta]{margin-top:26px;border-bottom:0;font-family:var(--sans);background:var(--gold);color:var(--ink-900);padding:16px 20px;font-size:13px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;transition:transform var(--t-press) var(--ease-out)}
[data-mobnav] [data-mobcta]:active{transform:scale(.98)}
/* Twelve pixels either side, given back by the group's negative margin so the
   first code still lines up with the links above. The codes were 14 to 20
   pixels wide: a target a thumb finds by luck. Now 38 to 44, and evenly
   spaced — a fixed minimum width made the gaps between codes uneven, because
   «EN» is wider than «IT». */
[data-moblang]{display:flex;gap:2px;margin:24px 0 0 -12px}
[data-moblang] a{padding:8px 12px;font-size:12px;font-weight:600;letter-spacing:.14em;color:var(--ink-045);-webkit-tap-highlight-color:transparent;transition:color var(--t-colour) ease}
[data-moblang] a[aria-current]{color:var(--gold);text-decoration:underline 1px;text-underline-offset:6px}

/* The sheet arrives rather than appears: a short fall and a fade, quicker than
   anything on the page, because it answers a tap. Closing is instant — a
   <details> takes its content away at once, and leaving fast is right. */
@media (prefers-reduced-motion: no-preference){
  [data-mobmenu][open] [data-mobnav]{animation:ibex-sheet-in .22s var(--ease-out)}
}
@keyframes ibex-sheet-in{from{opacity:0;transform:translateY(-6px)}}

/* The page under the sheet stays where it is. Without this a swipe on the
   sheet scrolled the page behind it, and closing the menu left the reader
   somewhere else. The gutter is held so a classic scrollbar does not take its
   width back and shift the header sideways. */
@media (max-width:1179.98px){
  html:has([data-mobmenu][open]){overflow:hidden;scrollbar-gutter:stable}
}

/* ── hover, press, and the chrome ─────────────────────────────────────────
   Hover only where there is a pointer that hovers. On a touch screen :hover
   sticks to whatever was tapped last, and a link left lit after the finger has
   gone reads as selected. */
@media (hover:hover) and (pointer:fine){
  [data-navlink]:hover{color:var(--chrome-fg)}
  [data-lang-btn]:not([aria-current]):hover{color:var(--chrome-fg)}
  [data-headercta]:hover{background-color:var(--chrome-acc);color:var(--chrome-on-acc)}
  [data-mobbtn]:hover{border-color:var(--chrome-fg)}
  [data-mobnav] > a:not([data-mobcta]):hover{color:var(--gold)}
  [data-moblang] a:not([aria-current]):hover{color:var(--ink-100)}
}
[data-headercta]:active{transform:scale(.98)}

/* ── the button, once ─────────────────────────────────────────────────────
   Six templates drew a button and no two drew the same one: 17/28 pixels of
   padding in the hero, 16/26 in the closing call and on the error pages, 16/26
   with a 48-pixel floor on the form, and a .3s transition on two of them that
   moved nothing, because nothing ever changed state. One rule now, three kinds:

     [data-btn="solid"]   the one filled control on a page: the hero's first
     [data-btn="accent"]  outlined in the accent: the primary everywhere else
     [data-btn]           outlined in the strong rule: the secondary

   THE TEXT OF A FILL IS --bg, which is what _band.html keeps that literal for:
   the band's own ground, so a filled button is lettered in the colour of the
   page it sits on. scripts/check_contrast.py measures every fill on all four
   bands — 4.91:1 at the lowest, the accent filled on the warm paper.

   Every colour here is a band token: none of it means anything outside a band,
   and nothing outside a band uses it. */
[data-btn]{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:15px 26px;border:1px solid var(--rl2);border-radius:0;background:transparent;color:var(--fg);font:600 12px/1.25 var(--sans);letter-spacing:.11em;text-transform:uppercase;text-align:center;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color var(--t-colour) ease,color var(--t-colour) ease,border-color var(--t-colour) ease,transform var(--t-press) var(--ease-out)}
[data-btn="solid"]{background:var(--acc);border-color:var(--acc);color:var(--bg)}
[data-btn="accent"]{border-color:var(--acc);color:var(--acc)}
/* Pressed, a control gives a little: two per cent, in a seventh of a second.
   It says the press was heard before the next page has begun to load. */
[data-btn]:active{transform:scale(.98)}

/* ── the enquiry form's fields ────────────────────────────────────────────
   Out of the style attribute, where no state could reach them: an inline
   border beats every selector, so a field could not change on hover and could
   not say it had been refused. */
[data-ibex-contact] input,
[data-ibex-contact] textarea{display:block;width:100%;min-height:48px;margin:0;padding:14px 16px;border:1px solid var(--rl2);border-radius:0;background:var(--rl);color:var(--fg);font:400 16px/1.7 var(--sans,inherit);transition:border-color var(--t-colour) ease,box-shadow var(--t-colour) ease}
[data-ibex-contact] textarea{resize:vertical}
/* A field the browser has refused. Twice the weight of the border and the
   band's ink: the palette has no red, and a second colour would say less than
   the thickness does — a difference that holds without colour vision. The
   browser's own message says why; ibex-contact.js sets the attribute and takes
   it away as soon as the field is acceptable. */
[data-ibex-contact] [aria-invalid="true"]{border-color:var(--fg);box-shadow:inset 0 0 0 1px var(--fg)}
[data-ibex-contact] a[href^="mailto:"]{font-size:14px;color:var(--mut);border-bottom:1px solid var(--rl2);transition:color var(--t-colour) ease,border-color var(--t-colour) ease}
/* What happened after the press, said on the page. The button hands over to
   the reader's mail program, and where there is none — a webmail user, a
   locked-down office machine — nothing visible happened at all. Empty, it is
   kept in the accessibility tree and out of the layout, so the announcement
   lands in a live region that already existed. */
[data-ibex-status]{margin:0;font-size:14px;line-height:var(--lh-prose);color:var(--fg);max-width:58ch;text-wrap:pretty}
[data-ibex-status]:empty{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ── links that are not in running text ───────────────────────────────────
   Each of these had its colour in a style attribute, which is why none of them
   answered a pointer: the hover rule had nothing it was allowed to override. */
[data-textlink]{font-size:12px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--acc);border-bottom:1px solid var(--rl2);transition:border-color var(--t-colour) ease}
[data-cardlink]{color:inherit;transition:color var(--t-colour) ease}
[data-artlink] h2{transition:color var(--t-colour) ease}
[data-footlink]{font-size:13px;color:var(--ink-060);transition:color var(--t-colour) ease}
[data-herocredit] a{transition:color var(--t-colour) ease}

@media (hover:hover) and (pointer:fine){
  [data-btn]:hover{border-color:var(--fg)}
  [data-btn="solid"]:hover{background:var(--fg);border-color:var(--fg)}
  [data-btn="accent"]:hover{background:var(--acc);border-color:var(--acc);color:var(--bg)}
  [data-ibex-contact] input:not([aria-invalid="true"]):hover,
  [data-ibex-contact] textarea:not([aria-invalid="true"]):hover{border-color:var(--mut)}
  [data-ibex-contact] a[href^="mailto:"]:hover{color:var(--fg);border-bottom-color:var(--fg)}
  [data-textlink]:hover{border-bottom-color:var(--acc)}
  [data-cardlink]:hover,
  [data-artlink]:hover h2{color:var(--acc)}
  [data-crumb]:hover{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1px}
  [data-footlink]:hover{color:var(--ink-100)}
  [data-herocredit] a:hover{color:var(--fg)}
}

@media (min-width:1180px){
  [data-desknav]{display:flex}
  [data-desklang]{display:flex}
  [data-headercta]{display:inline-block}
  [data-mobmenu]{display:none}
}

/* ── the grids ─────────────────────────────────────────────────────────────
   Every banded grid on the site, at the widths ibex-layout.js used to apply
   them — the same eight hooks, the same thresholds, the same tracks, moved
   here on 10.10.2026 and measured equal before and after on all 52 pages at
   thirteen widths, the boundaries on both sides.

   WHY THEY LEFT THE SCRIPT. It ran `defer`, after the document had been
   parsed, and a browser is free to paint before that: the first frame of
   every page was the markup's own default and the second was the real grid.
   Those defaults are not all one column — people.html writes four, the cards
   in section.html three — so on a phone the team arrived as four 60-pixel
   columns and then fell into one, and on a desktop every two-column band
   started as a stack and jumped. A media query is resolved before the first
   frame, holds without JavaScript, and needs no resize listener.

   !important because the markup still carries its default in a style
   attribute, as the fallback for a page whose stylesheet failed to load, and
   an inline declaration beats any selector without it. */
[data-cols4],[data-cols3],[data-cols2],[data-dl],[data-ctagrid],[data-artgrid],[data-herogrid],[data-splitgrid]{grid-template-columns:minmax(0,1fr) !important}
@media (min-width:760px){
  [data-cols4],[data-cols3]{grid-template-columns:repeat(2,minmax(0,1fr)) !important}
}
@media (min-width:900px){
  [data-cols2]{grid-template-columns:repeat(2,minmax(0,1fr)) !important}
  [data-ctagrid]{grid-template-columns:minmax(0,1fr) minmax(0,0.9fr) !important}
  /* The two shapes the static original built every wide band out of, under
     thirteen names, with ratios between 0.8fr and 1.45fr all switching at
     900. These are the middle of each cluster. */
  [data-herogrid]{grid-template-columns:minmax(0,1.45fr) minmax(0,1fr) !important}
  [data-splitgrid]{grid-template-columns:minmax(0,0.9fr) minmax(0,1.1fr) !important}
}
@media (min-width:940px){
  [data-dl]{grid-template-columns:0.42fr minmax(0,1fr) !important}
}
@media (min-width:1080px){
  [data-artgrid]{grid-template-columns:0.28fr minmax(0,1fr) !important}
}
@media (min-width:1180px){
  [data-cols4]{grid-template-columns:repeat(4,minmax(0,1fr)) !important}
  [data-cols3]{grid-template-columns:repeat(3,minmax(0,1fr)) !important}
}

/* Four columns is one per group. Below 900 they would be 180px wide and a page
   title would break across three lines, so they become one column. */
@media (max-width:900px){
  [data-footgrid]{grid-template-columns:minmax(0,1fr) !important}
}

/* Il telefono e l'indirizzo nel piede, che erano gli unici due bersagli della
   pagina sotto misura.

   Misurati a 1440px: alti 14 pixel, e i due centri a 20,7 pixel l'uno
   dall'altro. Il 2.5.8 (AA) chiede 24×24, oppure — per un bersaglio piu'
   piccolo — che due cerchi di 24 pixel di diametro centrati sui due non si
   tocchino. 20,7 contro 24: mancavano 3,3 pixel. Gli altri diciannove
   bersagli sotto misura della pagina passano tutti per spaziatura; questi due
   no, perche' stanno in due paragrafi separati da sei pixel.

   Ventiquattro pixel di altezza soddisfano il criterio invece di un'eccezione,
   e portano i centri a 30,5: passano anche per spaziatura, con margine. Il
   piede cresce di venti pixel su 549.

   LA SPECIFICITA' E' LA REGOLA, non un dettaglio. `[data-contact]` vale (0,1,0)
   e sta SOTTO al `footer a[href]` di ibex-responsive.css, che vale (0,1,2):
   su un puntatore grossolano vince quello e questi due restano a 44 pixel come
   ogni altro link del piede. Un selettore piu' preciso — `footer p
   a[href^="tel:"]` — vincerebbe lui, e ridurrebbe il bersaglio sul telefono da
   44 a 24 mentre sembra che lo stia allargando.

   Non si usa l'imbottitura del blocco telefono qui sotto, che sembra fatta
   apposta: quella regola vive dentro @media (max-width:640px) e non tocca il
   desktop, dov'e' il difetto. E i suoi 13px con margine negativo lascerebbero
   qui due scatole da 40 pixel a 20,7 di distanza, sovrapposte per venti —
   meta' del numero di telefono aprirebbe la posta.

   Quella regola portava anche un secondo selettore, [data-linkbtn], che
   nessun elemento ha mai avuto: tolto il 02.09.2026 con ESC-22. Il
   ragionamento qui sopra riguarda l'imbottitura e non il gancio, quindi resta
   intero senza di esso — ed e' il motivo per cui vale la pena tenerlo scritto:
   e' la misura che spiega perche' [data-contact] sta a 24 e non a 44. */
[data-contact]{min-height:24px;display:inline-flex;align-items:center}

/* ---- the phone, which is not the desktop made smaller -------------------- */
@media (max-width:640px){
  /* Sixteen pixels in a 335px column reads at forty-two characters a line,
     below the forty-five where prose stops feeling choppy. Fifteen buys the
     three that were missing without the text becoming small.

     !important because this site styles almost everything inline, and an
     inline declaration beats any selector. It is not a shortcut here, it is
     the only way a stylesheet can speak at all. */
  .rich-text,.rich-text p,.rich-text li,main dd,main li{font-size:15px !important}

  /* A standalone link is a target on a phone, and these were seventeen pixels
     tall. The padding is vertical only and negative-margined back out, so
     nothing moves — the target grows, the design does not.

     a[href]: un'ancora senza href non è un bersaglio, e allargarla darebbe
     43 px di area di tocco a una parola su cui non si può toccare niente. */
  .rich-text a[href]{padding-block:13px;margin-block:-13px;display:inline-block}
}
