/* ==========================================================================
 * KuramaLab — foglio di stile pubblico.
 *
 * Sistema visivo condiviso con l'API Hub (api.kuramalab.net): stessi token,
 * stessi font, stessi componenti firma (eyebrow + index-mark, rule, badge,
 * panel--marked). I due siti sono nodi dello stesso network e devono
 * riconoscersi a colpo d'occhio.
 *
 * Nessun framework, nessun runtime: un solo file, letto dall'alto in basso.
 *
 * Sezioni:
 *   01 TOKEN            06 COMPONENTI HUB      11 MOVIMENTO RIDOTTO
 *   02 FONT             07 SEZIONI DI PAGINA
 *   03 BASE             08 NETWORK
 *   04 LAYOUT           09 ACCESSO
 *   05 HEADER/FOOTER    10 RESPONSIVE
 * ========================================================================== */

/* ------------------------------------------------------------------ 01 TOKEN
 * Due livelli, come nell'hub:
 *   - token GREZZI (ink, paper, ember, gold): valori fissi, usati quando una
 *     superficie e' deliberatamente scura dentro una pagina chiara;
 *   - token SEMANTICI (surface, line, fg, accent, ok/warn/danger/info):
 *     ridefiniti da `.on-dark`, cosi' lo stesso componente rende bene su
 *     entrambi i fondi senza duplicare markup.
 * -------------------------------------------------------------------------- */
:root {
    color-scheme: light;

    --color-ink-950: #14110f;
    --color-ink-900: #1c1917;
    --color-ink-800: #2a2522;
    --color-ink-700: #3d3733;
    --color-ink-600: #5a524c;
    --color-ink-500: #7a716a;
    --color-ink-400: #9c948c;
    --color-ink-300: #c3bcb4;
    --color-ink-200: #ded8d1;
    --color-ink-100: #efebe6;
    --color-paper: #fbf9f6;
    --color-paper-raised: #ffffff;

    --color-ember-700: #9a3b06;
    --color-ember-600: #c24a08;
    --color-ember-500: #e8590c;
    --color-ember-400: #f5822b;
    --color-ember-100: #fde9d8;
    --color-gold-400: #e0a83b;

    --color-ok: #2f6f4e;
    --color-ok-bg: #e8f1ea;
    --color-warn: #8a5b00;
    --color-warn-bg: #fbf0d9;
    --color-danger: #a62b1f;
    --color-danger-bg: #f8e7e4;
    --color-info: #1f5f63;
    --color-info-bg: #e3efef;

    --color-surface: var(--color-paper);
    --color-surface-raised: var(--color-paper-raised);
    --color-surface-sunken: var(--color-ink-100);
    --color-line: var(--color-ink-200);
    /* Bordo dei CONTROLLI, non separatore: WCAG 1.4.11 chiede >= 3:1. */
    --color-line-strong: #948b83;
    /* Tre livelli di testo smorzato, tutti >= 4,5:1 sulle superfici chiare. */
    --color-fg: var(--color-ink-900);
    --color-fg-muted: var(--color-ink-600);
    --color-fg-subtle: #6b625b;
    --color-fg-faint: #726960;
    --color-accent: var(--color-ember-600);
    --color-accent-hover: var(--color-ember-500);
    --color-accent-soft: var(--color-ember-100);
    --color-on-accent: #ffffff;
    --color-focus: var(--color-ink-950);

    --font-display: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
    --font-sans: 'IBM Plex Sans', 'Segoe UI', system-ui, sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', monospace;

    --radius-xs: 2px;
    --radius-md: 4px;
    --radius-lg: 6px;
    --radius-2xl: 16px;

    --shell-max: 1200px;
    --shell-gutter: 24px;

    --space-1: 8px;
    --space-2: 16px;
    --space-3: 24px;
    --space-4: 40px;
    --space-5: 64px;

    --ease: cubic-bezier(.2, .7, .2, 1);
}

/* Contesto scuro. Non e' un tema utente: sono le FASCE deliberatamente scure
 * (hero, sezioni ink, footer). Ridefinendo qui i soli token semantici, badge,
 * rule, eyebrow e pannelli funzionano identici senza varianti di markup. */
.on-dark {
    color-scheme: dark;

    --color-surface: var(--color-ink-950);
    --color-surface-raised: var(--color-ink-900);
    --color-surface-sunken: var(--color-ink-900);
    --color-line: var(--color-ink-800);
    --color-line-strong: var(--color-ink-500);
    --color-fg: #f0ebe5;
    --color-fg-muted: #b9b0a8;
    --color-fg-subtle: #9c948c;
    --color-fg-faint: #8a827a;
    --color-accent: var(--color-ember-400);
    --color-accent-hover: var(--color-ember-500);
    --color-accent-soft: var(--color-ink-800);
    --color-on-accent: var(--color-ink-950);
    --color-focus: var(--color-gold-400);

    --color-ok: #6fbf8e;
    --color-ok-bg: #1b2f24;
    --color-warn: #e3b457;
    --color-warn-bg: #33280f;
    --color-danger: #f08c7e;
    --color-danger-bg: #38201c;
    --color-info: #6bc4c9;
    --color-info-bg: #16302f;
}

/* ------------------------------------------------------------------- 02 FONT
 * Self-hosted, nessuna CDN. `swap` perche' un testo invisibile e' peggio di un
 * salto tipografico. Gli unicode-range separano latin da latin-ext: i .woff2
 * dell'estensione non vengono scaricati per una pagina che non li usa.
 * -------------------------------------------------------------------------- */
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/space-grotesk-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/space-grotesk-latin-ext-500-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/space-grotesk-latin-700-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('/fonts/space-grotesk-latin-ext-700-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-ext-400-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-ext-500-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('/fonts/ibm-plex-sans-latin-ext-600-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('/fonts/ibm-plex-mono-latin-ext-400-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'IBM Plex Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('/fonts/ibm-plex-mono-latin-ext-500-normal.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------- 03 BASE */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    /* Larghezza della barra di scorrimento riservata sempre, anche sulle
     * pagine piu' corte che non ne hanno bisogno: senza, il passaggio fra una
     * pagina con e una senza barra fa slittare il testo di ~15px e, sulle
     * pagine con paragrafi lunghi, puo' cambiare il numero di righe e quindi
     * l'altezza del documento (visibile come fascia chiara sotto il piede di
     * pagina negli screenshot a pagina intera, e come un piccolo scatto di
     * layout per chi visita il sito da schermi stretti). */
    scrollbar-gutter: stable;
}

body {
    margin: 0;
    background-color: var(--color-surface);
    color: var(--color-fg);
    font-family: var(--font-sans);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

img {
    max-width: 100%;
}

a {
    color: inherit;
}

h1,
h2,
h3 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.12;
}

/* Ogni cifra allineata sotto la precedente: importi, stelle, date, indici. */
.index-mark,
.repo-table td,
.repo-table th,
.preview-row,
.network-card__value,
.method-steps span,
.scenario-grid span,
.capability-label,
.article-meta {
    font-variant-numeric: tabular-nums;
}

:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 3px;
}

.skip-link {
    position: absolute;
    left: 16px;
    top: -100px;
    z-index: 80;
    padding: 10px 16px;
    background-color: var(--color-paper-raised);
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-md);
    color: var(--color-ink-900);
    font-weight: 600;
    text-decoration: none;
}

.skip-link:focus {
    top: 16px;
}

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

/* ----------------------------------------------------------------- 04 LAYOUT */
.shell {
    width: min(var(--shell-max), 100% - (2 * var(--shell-gutter)));
    margin-inline: auto;
}

.section {
    padding-block: clamp(56px, 8vw, 88px);
}

.section--raised {
    background-color: var(--color-paper-raised);
    border-block: 1px solid var(--color-ink-200);
}

.section--ink {
    background-color: var(--color-ink-900);
    color: #f0ebe5;
}

.section--ink-950 {
    background-color: var(--color-ink-950);
    color: #f0ebe5;
}

/* ------------------------------------------------------- 05 HEADER E FOOTER */
.public-header {
    position: sticky;
    top: 0;
    z-index: 50;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    background-color: rgba(20, 17, 15, 0.95);
    backdrop-filter: blur(12px);
    color: #ffffff;
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    min-height: 60px;
    padding-block: 10px;
}

/* Marchio: logo intero (fiamma + wordmark), stesso file in header e footer
 * tramite il componente <x-brand-logo>. L'altezza varia per contesto tramite
 * le classi brand-logo--header / brand-logo--footer (niente style inline: la
 * CSP vieta style-src inline); il breakpoint mobile dell'header la
 * sovrascrive qui sotto, in sezione 09, senza toccare il markup. */
.brand-lockup {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    text-decoration: none;
}

.brand-logo {
    display: block;
    width: auto;
}

.brand-logo--header {
    height: 48px;
}

.brand-logo--footer {
    height: 52px;
}

.public-nav {
    display: flex;
    align-items: center;
    gap: clamp(14px, 2vw, 26px);
    font-size: 0.875rem;
    font-weight: 500;
}

.public-nav a {
    padding-block: 6px;
    border-bottom: 2px solid transparent;
    color: #ffffff;
    text-decoration: none;
}

.public-nav a:hover {
    color: var(--color-ember-400);
}

.public-nav a.is-current {
    border-bottom-color: var(--color-ember-400);
    color: var(--color-ember-400);
}

.public-header :focus-visible {
    outline-color: var(--color-gold-400);
}

.mobile-nav {
    display: none;
    position: relative;
}

.mobile-nav summary {
    display: flex;
    align-items: center;
    gap: 8px;
    min-height: 40px;
    padding-inline: 12px;
    border: 1px solid var(--color-ink-700);
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
    list-style: none;
    cursor: pointer;
}

.mobile-nav summary::-webkit-details-marker {
    display: none;
}

.mobile-nav[open] summary span {
    transform: rotate(45deg);
}

.mobile-nav summary span {
    display: inline-block;
    font-size: 1.1rem;
    line-height: 1;
}

.mobile-nav nav {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    display: grid;
    min-width: 13rem;
    padding: 6px;
    border: 1px solid var(--color-ink-700);
    border-radius: var(--radius-lg);
    background-color: var(--color-ink-900);
}

.mobile-nav nav a {
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 8px 14px;
    border-radius: var(--radius-md);
    color: #ffffff;
    font-size: 0.9375rem;
    text-decoration: none;
}

.mobile-nav nav a:hover,
.mobile-nav nav a.is-current {
    background-color: var(--color-ink-800);
    color: var(--color-ember-400);
}

.public-footer {
    padding-block: var(--space-5) var(--space-4);
    background-color: var(--color-ink-950);
    color: var(--color-ink-300);
    font-size: 0.875rem;
}

/* Quattro colonne di uguale larghezza: le voci omologhe cadono sempre nella
 * stessa posizione orizzontale, indipendentemente dalla lunghezza dei testi. */
.footer-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4) var(--space-3);
}

/* Modulo Network spento: la sua colonna non c'e' e le tre rimaste si
 * ridividono lo spazio, invece di lasciare una quarta colonna vuota. `:where`
 * tiene la specificita' uguale a `.footer-grid`, cosi' le soglie della sezione
 * 10 (due colonne, poi una) continuano a valere. */
.footer-grid:where(:not(:has(#footer-network))) {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.footer-column p,
.footer-column a {
    margin: 0;
}

.footer-title {
    margin-bottom: 12px;
    color: #ffffff;
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 700;
}

.footer-column a {
    display: block;
    margin-top: 8px;
    color: var(--color-ink-300);
    text-decoration: none;
}

.footer-column a:hover {
    color: #ffffff;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.footer-column .footer-hub-link {
    color: var(--color-ember-400);
}

.footer-brand p {
    margin-top: 12px;
    max-width: 30ch;
}

/* Riga del titolare (copyright, partita IVA, sede): voci centrate separate da
 * un punto, che vanno a capo per voce intera. Sotto i 760px una voce per riga
 * e niente separatori (sezione 10). Cifre tabulari per la partita IVA. */
.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px 10px;
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-ink-800);
    font-variant-numeric: tabular-nums;
    text-align: center;
}

/* Una partita IVA non si spezza mai fra due righe. */
.footer-vat {
    white-space: nowrap;
}

.public-footer :focus-visible {
    outline-color: var(--color-gold-400);
}

/* --------------------------------------------------------- 06 COMPONENTI HUB
 * Riprodotti 1:1 dal foglio dell'API Hub: sono la firma condivisa dei due siti.
 * -------------------------------------------------------------------------- */
.eyebrow,
.kicker,
.capability-label,
.article-meta {
    display: block;
    margin: 0;
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-fg-subtle);
}

.index-mark {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    color: var(--color-fg-subtle);
}

/* La regola: traccia a tre segmenti dorati + hairline. Flex e non
 * `border-bottom` proprio per poter ospitare la traccia. */
.rule {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-block: 12px 24px;
}

.rule::before {
    content: '';
    width: 24px;
    height: 12px;
    flex: none;
    background-repeat: no-repeat;
    background-position: left center;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='12' viewBox='0 0 24 12'%3E%3Cg fill='none' stroke='%23E0A83B' stroke-opacity='0.55' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M2 10 8 2'/%3E%3Cpath d='M9 10 15 2'/%3E%3Cpath d='M16 10 22 2'/%3E%3C/g%3E%3C/svg%3E");
}

.rule::after {
    content: '';
    flex: 1 1 auto;
    height: 1px;
    background-color: var(--color-line);
}

/* `--color-line` e' misurato sulla carta: su fondo scuro la regola sparirebbe. */
.rule--inverse::after {
    background-color: rgba(255, 255, 255, 0.15);
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 20px;
    padding-inline: 6px;
    border: 1px solid transparent;
    border-radius: var(--radius-xs);
    background-color: var(--color-surface-sunken);
    color: var(--color-fg-muted);
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.badge--ok {
    background-color: var(--color-ok-bg);
    color: var(--color-ok);
}

.badge--warn {
    background-color: var(--color-warn-bg);
    color: var(--color-warn);
}

.badge--danger {
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
}

.badge--info {
    background-color: var(--color-info-bg);
    color: var(--color-info);
}

.badge--muted {
    background-color: transparent;
    border-color: var(--color-line-strong);
    color: var(--color-fg-muted);
}

.panel {
    position: relative;
    padding: var(--space-3);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    background-color: var(--color-surface-raised);
}

/* Tacche d'angolo ember: il dettaglio che identifica un pannello primario
 * KuramaLab. Puramente decorativo, invisibile agli screen reader. */
.panel--marked::before,
.panel--marked::after {
    content: '';
    position: absolute;
    width: 8px;
    height: 8px;
    border-color: var(--color-ember-600);
    border-style: solid;
    pointer-events: none;
}

.panel--marked::before {
    top: -1px;
    left: -1px;
    border-width: 2px 0 0 2px;
}

.panel--marked::after {
    right: -1px;
    bottom: -1px;
    border-width: 0 2px 2px 0;
}

.on-dark .panel--marked::before,
.on-dark .panel--marked::after {
    border-color: var(--color-ember-400);
}

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 12px 24px;
    border: 1px solid var(--color-accent);
    border-radius: var(--radius-lg);
    background-color: var(--color-accent);
    color: var(--color-on-accent);
    font-family: var(--font-sans);
    font-size: 0.9375rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.16s var(--ease);
}

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

.button--secondary,
.button-light {
    border-color: var(--color-line-strong);
    background-color: transparent;
    color: currentColor;
}

.button--secondary:hover,
.button-light:hover {
    background-color: var(--color-surface-sunken);
    border-color: var(--color-line-strong);
}

/* Azione che annulla o toglie qualcosa ("Non sono stato io"): a contorno, nel
   rosso del tema, leggibile sia sul fondo chiaro sia su quello scuro. */
.button--danger {
    border-color: var(--color-danger);
    background-color: transparent;
    color: var(--color-danger);
}

.button--danger:hover {
    border-color: var(--color-danger);
    background-color: var(--color-danger-bg);
}

.text-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--color-accent);
    font-weight: 600;
    text-decoration: none;
}

.text-link:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.text-link span {
    transition: transform 0.2s var(--ease);
}

.text-link:hover span {
    transform: translateX(3px);
}

.external-link::after {
    content: ' \2197';
}

/* -------------------------------------------------- 07 SEZIONI DI PAGINA */
/* Intestazione di sezione: eyebrow numerata -> h2 -> paragrafo -> rule. */
.editorial-heading,
.section-heading {
    max-width: 46rem;
    margin-bottom: var(--space-4);
}

.editorial-heading h2,
.section-heading h2 {
    margin: 12px 0 0;
    font-size: clamp(1.75rem, 3vw, 2.25rem);
}

.editorial-heading > p:not(.eyebrow):not(.kicker),
.section-heading > p:not(.eyebrow):not(.kicker) {
    margin: 16px 0 0;
    max-width: 44rem;
    color: var(--color-fg-muted);
    line-height: 1.7;
}

.section--ink .editorial-heading > p:not(.eyebrow),
.section--ink-950 .editorial-heading > p:not(.eyebrow) {
    color: var(--color-ink-300);
}

.evidence-note {
    font-size: 0.875rem;
}

/* --- HERO scuro, con overlay radiale e griglia asimmetrica come sull'hub. */
.hero {
    position: relative;
    overflow: hidden;
    background-color: var(--color-ink-950);
    color: #ffffff;
}

.hero::before {
    content: '';
    position: absolute;
    inset: 0;
    opacity: 0.4;
    background:
        radial-gradient(circle at 75% 20%, rgba(217, 119, 6, 0.35), transparent 34%),
        radial-gradient(circle at 10% 80%, rgba(15, 118, 110, 0.2), transparent 32%);
    pointer-events: none;
}

/* L'immagine di scena resta (preload e riferimento invariati), ma solo come
 * texture appena percepibile: scrim scuro UNIFORME (niente gradiente che
 * lascia una macchia piu' chiara da un lato) e opacita' complessiva bassa,
 * cosi' l'hero resta coerente con l'hub, che usa solo il gradiente radiale. */
.hero--home::after {
    content: '';
    position: absolute;
    inset: 0;
    opacity: 0.1;
    background:
        linear-gradient(0deg, rgba(20, 17, 15, 0.9), rgba(20, 17, 15, 0.9)),
        url('/assets/visuals/connected-operations-hero-v1.webp') center / cover no-repeat;
    pointer-events: none;
}

.hero-grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: center;
    gap: clamp(32px, 5vw, 56px);
    padding-block: clamp(56px, 9vw, 104px);
}

/* Modulo Network spento: niente pannello di anteprima, il testo occupa la
 * griglia intera invece di lasciare vuota la colonna di destra. */
.hero-grid:where(:not(:has(.preview-panel))) {
    grid-template-columns: minmax(0, 1fr);
}

.hero .eyebrow,
.hero .index-mark {
    color: var(--color-ember-400);
}

.hero h1 {
    margin: 20px 0 0;
    max-width: 20ch;
    /* Stessa scala dell'hub (60px su desktop): l'hero della home non deve
     * distaccarsi dalle dimensioni tipografiche del resto del network. */
    font-size: clamp(2.5rem, 4.6vw, 3.75rem);
    line-height: 1.08;
}

.hero-copy {
    margin: 24px 0 0;
    max-width: 44rem;
    color: var(--color-ink-300);
    font-size: 1.0625rem;
    line-height: 1.75;
}

.actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    max-width: 34rem;
    margin-top: var(--space-4);
}

.hero .button--secondary {
    border-color: var(--color-ink-600);
    color: #ffffff;
}

.hero .button--secondary:hover {
    background-color: var(--color-ink-900);
}

.hero-hub-link {
    display: inline-flex;
    color: var(--color-ink-300);
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
}

.hero-hub-link:hover {
    color: #ffffff;
}

/* Freccia dei collegamenti esterni: distanziata dal testo e mai attaccata. */
.hero-hub-link [aria-hidden],
.footer-column a [aria-hidden],
.network-card__title a [aria-hidden],
.repo-table__link [aria-hidden] {
    margin-left: 4px;
}

/* --- Fascia a tre affermazioni, con divisori condivisi. */
.claim-band {
    background-color: var(--color-paper-raised);
    border-bottom: 1px solid var(--color-ink-200);
}

.claim-band .shell {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.claim-band p {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 80px;
    margin: 0;
    padding: 16px 20px;
    border-left: 1px solid var(--color-line);
    color: var(--color-fg);
    font-size: 0.9375rem;
    font-weight: 500;
    text-align: center;
}

.claim-band p:first-child {
    border-left: 0;
}

/* --- Intestazioni di pagina interne (page-intro / visual-intro). */
.page-intro {
    position: relative;
    overflow: hidden;
    padding-block: clamp(48px, 7vw, 80px);
    background-color: var(--color-ink-950);
    color: #ffffff;
}

.page-intro .kicker,
.page-intro .eyebrow,
.page-intro .index-mark {
    color: var(--color-ember-400);
}

.page-intro h1,
.error-page h1 {
    margin: 12px 0 0;
    max-width: 22ch;
    font-size: clamp(2rem, 3.8vw, 3rem);
}

.page-intro > p,
.page-intro .visual-intro-inner > p {
    margin: 20px 0 0;
    max-width: 44rem;
    color: var(--color-ink-300);
    line-height: 1.75;
}

.visual-intro::before {
    content: '';
    position: absolute;
    inset: 0;
    opacity: 0.16;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    pointer-events: none;
}

.visual-intro--systems::before {
    background-image: url('/assets/visuals/connected-operations-hero-v1.webp');
}

.visual-intro--agentic::before {
    background-image: url('/assets/visuals/human-supervised-ai-v1.webp');
}

.visual-intro--physical::before {
    background-image: url('/assets/visuals/field-to-software-v1.webp');
}

.visual-intro-inner {
    position: relative;
    z-index: 1;
}

/* --- Griglie di card. Le card di solo testo (etichetta, titolo, testo: tre
 * figli, sempre) sono subgrid di tre righe della griglia madre: etichette,
 * titoli e testi di card sulla stessa fila partono alla stessa altezza anche
 * quando un titolo va a capo o un testo e' piu' corto, senza vuoti fra titolo
 * e testo. Le card degli articoli hanno righe proprie (immagine facoltativa,
 * etichetta, titolo, riassunto): li' conta che la riga finale cada in basso. */
.scenario-grid,
.capability-grid,
.feature-grid,
.principle-grid,
.article-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2);
}

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

.scenario-grid > article,
.capability-grid > article,
.feature-grid > article,
.principle-grid > article,
.article-card {
    display: grid;
    padding: var(--space-3);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-2xl);
    background-color: var(--color-surface-raised);
}

.scenario-grid > article,
.capability-grid > article,
.feature-grid > article,
.principle-grid > article {
    /* Subgrid: etichetta, titolo e testo delle card di una stessa fila partono
       alla stessa altezza anche con testi di lunghezza diversa. Un browser
       senza subgrid ignora la regola e impila i tre elementi: nessuna rottura. */
    grid-row: span 3;
    grid-template-rows: subgrid;
    /* Dentro la card nessuno spazio fra le righe: le distanze restano quelle
       dei margini dei titoli. */
    row-gap: 0;
}

/* Immagine, etichetta, titolo, riassunto: righe dichiarate e posti fissi.
   La prima riga ha sempre la stessa altezza: l'immagine o, senza, il
   segnaposto della stessa proporzione (`.article-card-placeholder`), cosi'
   etichetta, titolo e data cadono alla stessa altezza in tutta la fila. La
   riga elastica e' quella del titolo, cosi' il riassunto cade in basso. Con
   la sola regola `auto 1fr auto` l'immagine spostava tutto di una riga e
   l'elastica finiva sull'etichetta, staccandola dal titolo. */
.article-card {
    grid-template-rows: auto auto 1fr auto;
    align-content: start;
}

.article-card > picture,
.article-card > .article-card-placeholder {
    grid-row: 1;
    margin-bottom: 12px;
}

.article-card > .article-meta {
    grid-row: 2;
}

.article-card > h2,
.article-card > h3 {
    grid-row: 3;
}

.article-card > p:not(.article-meta) {
    grid-row: 4;
}

.section--ink .capability-grid > article,
.section--ink-950 .capability-grid > article,
.section--ink .feature-grid > article,
.section--ink-950 .feature-grid > article {
    border-color: var(--color-ink-700);
    background-color: var(--color-ink-800);
}

.scenario-grid h3,
.capability-grid h3,
.feature-grid h3,
.feature-grid h2,
.principle-grid h2,
.method-steps h3 {
    margin: 20px 0 8px;
    font-size: 1.125rem;
}

.scenario-grid p:not(.eyebrow):not(.kicker),
.capability-grid p:not(.capability-label),
.feature-grid p:not(.kicker),
.principle-grid p:not(.kicker),
.method-steps p {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: 0.9375rem;
    line-height: 1.7;
}

.section--ink .capability-grid p:not(.capability-label),
.section--ink-950 .capability-grid p:not(.capability-label) {
    color: var(--color-ink-300);
}

.section--ink .capability-label,
.section--ink-950 .capability-label,
.section--ink .eyebrow,
.section--ink-950 .eyebrow,
.section--ink .kicker,
.section--ink-950 .kicker,
.section--ink .index-mark,
.section--ink-950 .index-mark {
    color: var(--color-ember-400);
}

.section--ink h2,
.section--ink h3,
.section--ink-950 h2,
.section--ink-950 h3 {
    color: #ffffff;
}

.section-action {
    margin: var(--space-3) 0 0;
}

.section--ink .section-action .text-link,
.section--ink-950 .section-action .text-link {
    color: var(--color-ember-400);
}

/* --- Elenco numerato del metodo: colonna dell'indice condivisa fra le voci. */
.method-layout {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    align-items: start;
    gap: clamp(32px, 6vw, 72px);
}

.method-intro {
    position: sticky;
    top: 92px;
}

.method-intro h2 {
    margin: 12px 0 0;
    font-size: clamp(1.6rem, 2.8vw, 2.125rem);
}

.method-intro > p {
    margin: 16px 0 var(--space-3);
    color: var(--color-fg-muted);
    line-height: 1.75;
}

.method-steps {
    display: grid;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--color-line);
    list-style: none;
}

.method-steps li {
    display: grid;
    grid-template-columns: 3.5rem minmax(0, 1fr);
    gap: var(--space-2);
    padding-block: var(--space-3);
    border-bottom: 1px solid var(--color-line);
}

.method-steps span,
.scenario-grid span:not(.badge) {
    font-family: var(--font-mono);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.08em;
    color: var(--color-fg-subtle);
}

.method-steps h3 {
    margin: 0 0 6px;
}

/* --- Elenco dei servizi: colonna dell'indice condivisa. */
.service-list {
    border-top: 1px solid var(--color-line);
}

.service-list article {
    display: grid;
    grid-template-columns: 6rem minmax(0, 1fr);
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-bottom: 1px solid var(--color-line);
}

.service-list span {
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    color: var(--color-fg-subtle);
}

.service-list h2 {
    margin: 0 0 8px;
    font-size: clamp(1.375rem, 2.4vw, 1.75rem);
}

.service-list h2 a {
    text-decoration: none;
}

.service-list p {
    margin: 0 0 12px;
    max-width: 48rem;
    color: var(--color-fg-muted);
}

.service-deliverables {
    margin: 0;
    padding-left: 1.1rem;
    color: var(--color-fg-muted);
    font-size: 0.9375rem;
}

.service-use-cases li {
    grid-template-columns: 3.5rem minmax(0, 1fr);
}

/* --- Fasce di richiamo. */
.callout {
    padding-block: var(--space-5);
    background-color: var(--color-ink-950);
    color: #ffffff;
}

.callout-inner,
.contact-band-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

.callout h2,
.contact-band h2 {
    margin: 12px 0 0;
    max-width: 32ch;
    font-size: clamp(1.5rem, 2.6vw, 2rem);
}

.callout .kicker,
.callout .index-mark {
    color: var(--color-ember-400);
}

.callout .button-light {
    border-color: var(--color-ink-600);
    color: #ffffff;
}

.callout .button-light:hover {
    background-color: var(--color-ink-900);
}

.contact-band {
    padding-block: var(--space-5);
    background-color: var(--color-ember-500);
    color: var(--color-ink-950);
}

.contact-band .eyebrow,
.contact-band .kicker,
.contact-band .index-mark {
    /* 0,72 dava 3,65:1 su --color-ember-500: sotto il 4,5:1 richiesto.
     * 0,88 misura 4,64:1. */
    color: rgba(20, 17, 15, 0.88);
}

.contact-band p {
    margin: 12px 0 0;
    max-width: 44rem;
    /* 0,82 dava 4,27:1 su --color-ember-500: sotto il 4,5:1 richiesto.
     * 0,9 misura 4,75:1. */
    color: rgba(20, 17, 15, 0.9);
}

.contact-band .button-light {
    border-color: var(--color-ink-950);
    background-color: var(--color-ink-950);
    color: #ffffff;
}

.contact-band .button-light:hover {
    background-color: var(--color-ink-900);
    border-color: var(--color-ink-900);
}

/* --- Articoli. */
/* Linguette di filtro per categoria: una sola riga appoggiata su una hairline,
   l'attiva marcata dalla linea accento. Il conteggio e' in cifre tabulari,
   cosi' i numeri restano incolonnati fra una linguetta e l'altra. */
.filter-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-line);
}

.filter-tab {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: -1px;
    padding: 10px 2px;
    border-bottom: 2px solid transparent;
    color: var(--color-fg-muted);
    font-family: var(--font-display);
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: none;
}

.filter-tab:hover {
    color: var(--color-fg);
}

.filter-tab.is-current {
    border-bottom-color: var(--color-accent);
    color: var(--color-fg);
}

.filter-tab__count {
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-fg-subtle);
}

.article-card {
    text-align: left;
}

/* Categoria e data sulla stessa riga: l'eyebrow generico e' `display: block`. */
.article-card .article-meta,
.article-page .article-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.article-card__category {
    color: var(--color-accent);
}

/* Ritorno all'elenco a sinistra, cambio lingua a destra: stessa riga, stesso
   ritmo in tutte le pagine articolo. */
.article-page__top {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.article-page__top .back-link {
    margin-bottom: 0;
}

.article-card h2,
.article-card h3 {
    margin: 12px 0 8px;
    font-size: 1.125rem;
}

.article-card h2 a,
.article-card h3 a {
    text-decoration: none;
}

.article-card h2 a:hover,
.article-card h3 a:hover {
    text-decoration: underline;
    text-decoration-color: var(--color-gold-400);
    text-underline-offset: 4px;
}

.article-card p:not(.article-meta) {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: 0.9375rem;
}

.article-card-media,
.article-featured-media-image,
.article-body-media-image {
    /* `max-width` sempre: se il file non arriva (derivato cancellato,
     * richiesta persa) il browser disegna il segnaposto dell'immagine rotta
     * alla misura dell'attributo `width` (1200px) e la pagina scorre di lato.
     * Misurato a 390px durante il collaudo. */
    max-width: 100%;
    height: auto;
    border-radius: var(--radius-md);
}

/* La card riempie la sua colonna, sempre con la proporzione dell'anteprima
 * social (1200x630): le immagini portate dal vecchio sito ne hanno di ogni
 * tipo, e card della stessa fila non devono avere altezze diverse.
 *
 * L'immagine in evidenza e quelle del testo no: la larghezza e' quella
 * dell'attributo `width` (il derivato piu' grande, al massimo 1200px),
 * limitata dalla colonna. Un'immagine piu' stretta della colonna, come le
 * schermate da 300px del vecchio sito, resta alla sua misura invece di essere
 * ingrandita e sgranata. */
.article-card-media {
    /* Blocco, non in linea: altrimenti sotto l'immagine resta lo spazio delle
     * discendenti del testo, e il segnaposto (senza) sarebbe piu' basso. */
    display: block;
    width: 100%;
    aspect-ratio: 40 / 21;
    object-fit: cover;
}

/* Segnaposto della card senza immagine: stessa proporzione, sfondo tenue coi
 * colori del sito e la fiamma del marchio (l'icona del sito, gia' servita
 * come favicon). Solo CSS: nessuna immagine da generare, nessuno stile in
 * linea (CSP `style-src 'self'`). */
.article-card-placeholder {
    display: block;
    width: 100%;
    aspect-ratio: 40 / 21;
    border-radius: var(--radius-md);
    background:
        url("../icon-192.png") center / auto 46% no-repeat,
        linear-gradient(135deg, var(--color-surface-sunken), var(--color-accent-soft));
}

.article-featured-media {
    margin: var(--space-3) 0;
}

/* Immagine dentro il corpo di un articolo (Markdown `![alt](/media/12)`, resa
 * dallo stesso componente dell'immagine in evidenza). Il margine e' in `em` e
 * non in `--space-3` perche' qui l'immagine sta nel ritmo del testo, fra due
 * paragrafi: la stessa misura del separatore `.prose hr`. */
.article-body-media {
    margin: 1.75em 0;
}

/* Un'immagine dentro una frase resta in linea e non deve sfondare la colonna
 * di testo: e' il caso raro, ma e' scrivibile. */
p > .article-body-media-image {
    vertical-align: middle;
}

.article-featured-media figcaption,
.article-body-media figcaption {
    margin-top: 8px;
    color: var(--color-fg-subtle);
    font-size: 0.8125rem;
}

.empty-state {
    grid-column: 1 / -1;
    margin: 0;
    padding: var(--space-3);
    border: 1px dashed var(--color-line-strong);
    border-radius: var(--radius-md);
    color: var(--color-fg-muted);
}

.article-page {
    max-width: 46rem;
    padding-block: clamp(40px, 6vw, 72px);
}

.breadcrumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 var(--space-3);
    padding: 0;
    list-style: none;
    color: var(--color-fg-subtle);
    font-size: 0.8125rem;
}

.breadcrumbs li + li::before {
    content: '/ ';
}

.back-link {
    display: inline-block;
    margin-bottom: var(--space-3);
    color: var(--color-accent);
    font-weight: 600;
    text-decoration: none;
}

.article-page h1 {
    margin: 8px 0 0;
    font-size: clamp(1.875rem, 3.6vw, 2.75rem);
}

.article-lead {
    margin: 16px 0 var(--space-3);
    color: var(--color-fg-muted);
    font-size: 1.125rem;
    line-height: 1.7;
}

.prose {
    font-size: 1.0625rem;
    line-height: 1.8;
}

.prose p {
    margin: 0 0 1.15em;
}

/* Riquadro di firma a fondo articolo: lo stesso pannello marcato della home
 * (`.panel--marked`), separato dal corpo perche' non e' testo del Markdown.
 * L'invito ai contatti sta sulla stessa riga della frase che lo introduce su
 * schermi larghi, sotto su schermi stretti (regola mobile in 09), dove il
 * pulsante prende tutta la larghezza come negli altri gruppi di azioni
 * (`.actions`). */
.article-signature {
    margin-top: var(--space-5);
}

.article-signature__author {
    margin: 8px 0 0;
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: 600;
}

.article-signature__positioning {
    margin: 8px 0 0;
    color: var(--color-fg-muted);
}

.article-signature__cta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-3);
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-line);
}

.article-signature__cta p {
    margin: 0;
    color: var(--color-fg-muted);
}

.content-panel {
    max-width: 46rem;
}

.pagination-wrap {
    margin-top: var(--space-4);
}

/* Paginazione (vista condivisa pagination/cms): le regole stavano in un
 * <style> nella vista, che la CSP `style-src 'self'` blocca. Caselle quadrate
 * della stessa misura, cifre tabulari. */
.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.pagination-summary {
    margin: 0;
    color: var(--color-fg-muted);
    font-variant-numeric: tabular-nums;
}

.pagination-pages {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
}

.pagination-link {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    background-color: var(--color-surface-raised);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}

.pagination-link.current {
    border-color: var(--color-accent);
    background-color: var(--color-accent);
    color: var(--color-on-accent);
}

.pagination-link.disabled {
    color: var(--color-fg-faint);
    opacity: 0.55;
}

/* --- Documenti legali: versione e data sotto il titolo. Il testo vero e
 * proprio e' reso dal motore Markdown condiviso (ContentRenderer) e prende
 * gli stili del blocco successivo, gli stessi del corpo degli articoli. */
.page-intro .legal-meta {
    margin: 16px 0 0;
    color: var(--color-ink-300);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
}

/* Testo reso dal Markdown: corpo degli articoli (`.prose`) e documenti legali
 * (`.legal-body`). Un solo blocco per entrambi: il motore che produce l'HTML
 * e' lo stesso, e due elenchi di regole gemelle finirebbero per divergere.
 * `.prose` porta in piu' la propria misura di testo (sopra, sezione della
 * pagina articolo); tutto il resto e' in comune. */
.prose h2,
.legal-body h2 {
    margin: 1.75em 0 0.5em;
    font-size: 1.375rem;
}

.prose h2:first-child,
.legal-body h2:first-child {
    margin-top: 0;
}

.prose h3,
.legal-body h3 {
    margin: 1.5em 0 0.5em;
    font-size: 1.125rem;
}

.prose ul,
.prose ol,
.legal-body ul,
.legal-body ol {
    margin: 0 0 1.15em;
    padding-left: 1.25rem;
}

.prose li + li,
.legal-body li + li {
    margin-top: 0.35em;
}

/* Citazioni, separatori e tabelle: gli altri blocchi che l'editor Markdown
 * permette di inserire. La tabella sta in un contenitore
 * (`markdown-table-scroll`, aggiunto da ContentRenderer) che scorre di lato
 * sugli schermi stretti: la pagina non si allarga mai. L'allineamento
 * delle colonne arriva come attributo `align`: le celle senza attributo
 * vanno a sinistra, quelle con l'attributo lo rispettano. */
.prose blockquote,
.legal-body blockquote {
    margin: 0 0 1.15em;
    padding: 2px 0 2px 16px;
    border-left: 3px solid var(--color-accent);
    color: var(--color-fg-muted);
}

.prose blockquote p:last-child,
.legal-body blockquote p:last-child {
    margin-bottom: 0;
}

.prose hr,
.legal-body hr {
    margin: 1.75em 0;
    border: 0;
    border-top: 1px solid var(--color-line);
}

.markdown-table-scroll {
    margin: 0 0 1.15em;
    overflow-x: auto;
}

.prose table,
.legal-body table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
    line-height: 1.6;
    font-variant-numeric: tabular-nums;
}

.prose th,
.prose td,
.legal-body th,
.legal-body td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--color-line);
    vertical-align: top;
}

.prose th:not([align]),
.prose td:not([align]),
.legal-body th:not([align]),
.legal-body td:not([align]) {
    text-align: left;
}

.prose thead th,
.legal-body thead th {
    border-bottom-color: var(--color-line-strong);
    font-weight: 700;
}

/* Variabile dei dati aziendali non compilata (`⟦pec: non compilata⟧`). La
 * pubblicazione lo impedisce; qui compare solo in una versione pubblicata
 * prima del controllo o dopo che un dato e' stato svuotato, e deve vedersi
 * come un buco, non confondersi con il testo. Stessa classe nell'anteprima
 * dell'area riservata (cms.css, sezione 14). */
.legal-variable-missing {
    padding: 0 4px;
    border: 1px dashed var(--color-danger);
    border-radius: 4px;
    background-color: var(--color-danger-bg);
    color: var(--color-danger);
    font-weight: 600;
    white-space: nowrap;
}

/* --- Contatti. */
.contact-panel {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
    gap: var(--space-4);
    padding: clamp(20px, 4vw, 40px);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-2xl);
    background-color: var(--color-surface-raised);
}

.contact-panel h2 {
    margin: 12px 0 12px;
    font-size: clamp(1.5rem, 2.6vw, 2rem);
}

.contact-panel p {
    color: var(--color-fg-muted);
}

.contact-form {
    display: grid;
    gap: var(--space-2);
    margin-top: var(--space-3);
}

.contact-form label {
    display: grid;
    gap: 6px;
    font-size: 0.875rem;
    font-weight: 600;
}

.contact-form input,
.contact-form textarea {
    padding: 10px 12px;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-md);
    background-color: var(--color-surface-sunken);
    color: var(--color-fg);
    font-family: inherit;
    font-size: 0.9375rem;
}

.contact-form textarea {
    min-height: 8rem;
}

/* `.contact-form label` (sopra) mette il grassetto a tutte le etichette e
 * vincerebbe per specificita': il consenso e' una frase, resta normale. */
.contact-form .contact-consent {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    font-weight: 400;
}

.contact-honeypot {
    position: absolute;
    left: -9999px;
}

.contact-form-status {
    margin: 0;
    font-size: 0.875rem;
}

/* Riquadro della verifica Cloudflare Turnstile (solo se configurata): il
 * widget ha una larghezza propria, qui resta allineato a sinistra con il
 * ritmo dei campi e non si allarga sulla griglia. */
.contact-turnstile {
    justify-self: start;
    min-height: 65px;
}

/* Durante l'invio il pulsante non accetta un secondo clic. */
.contact-form button[disabled] {
    opacity: 0.6;
    cursor: progress;
}

/* Etichetta a sinistra, valore a destra, colonne identiche fra le righe. */
.contact-facts {
    border-top: 1px solid var(--color-line);
}

.contact-facts p {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: var(--space-2);
    margin: 0;
    padding-block: 12px;
    border-bottom: 1px solid var(--color-line);
}

.contact-facts span {
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-fg-subtle);
}

.contact-facts strong,
.contact-facts a {
    justify-self: end;
    font-weight: 600;
    text-align: right;
    text-decoration: none;
}

.field-error,
.form-error,
.errors {
    color: var(--color-danger);
    font-size: 0.875rem;
}

/* Lo span di errore di ogni campo del modulo contatti (contact-form.js) resta
 * nel markup anche senza errore, vuoto: tolto dal flusso, cosi' non lascia
 * uno spazio vuoto nel gap della griglia `.contact-form` quando non serve. */
.field-error:empty {
    display: none;
}

/* --- 404. */
.error-page {
    padding-block: clamp(72px, 12vw, 128px);
}

.error-page > p:not(.kicker) {
    max-width: 34rem;
    margin: 16px 0 var(--space-3);
    color: var(--color-fg-muted);
}

/* ---------------------------------------------------------------- 08 NETWORK
 * Le card del network condividono la stessa griglia interna (`auto 1fr auto`):
 * badge in alto, descrizione elastica, riga "Accesso" incollata in basso. E'
 * cio' che fa cadere la riga finale alla STESSA altezza in tutte le card
 * sorelle, invece di lasciarla seguire la lunghezza del testo.
 * -------------------------------------------------------------------------- */
.network-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-2);
}

/* In home le card featured sono 4: 3 colonne lascerebbero una card orfana
 * (3+1), quindi qui si passa a 2x2. La card resta lo stesso componente. */
.network-grid--pairs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.network-card {
    display: grid;
    grid-template-rows: auto auto 1fr auto;
    gap: 12px;
    padding: var(--space-3);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-2xl);
    background-color: var(--color-surface-raised);
}

.network-card__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.network-card__badges {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
}

.network-card__title {
    margin: 0;
    font-size: 1.125rem;
}

.network-card__title a {
    text-decoration: none;
}

.network-card__title a:hover {
    text-decoration: underline;
    text-decoration-color: var(--color-gold-400);
    text-underline-offset: 4px;
}

.network-card__summary {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: 0.9375rem;
    line-height: 1.7;
}

/* Etichetta a sinistra, valore a destra: due sole colonne, identiche in tutte
 * le card, cosi' "Accesso" e il suo valore sono incolonnati fra i fratelli. */
.network-card__meta {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-2);
    padding-top: 12px;
    border-top: 1px solid var(--color-line);
}

.network-card__label {
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-fg-subtle);
}

.network-card__value {
    justify-self: end;
    font-size: 0.875rem;
    font-weight: 600;
}

.section--ink .network-card,
.section--ink-950 .network-card {
    border-color: var(--color-ink-700);
    background-color: var(--color-ink-800);
}

.section--ink .network-card__summary,
.section--ink-950 .network-card__summary {
    color: var(--color-ink-300);
}

/* Stesso schiarimento del sommario: senza, etichetta e badge restano al
 * valore chiaro-su-chiaro pensato per la carta (2,54:1 e 1,98:1 su
 * --color-ink-800, sotto il 4,5:1 richiesto). */
.section--ink .network-card__label,
.section--ink-950 .network-card__label,
.section--ink .network-card .badge--muted,
.section--ink-950 .network-card .badge--muted {
    color: var(--color-ink-300);
}

/* --- Pannello "Anteprima del network" nell'hero: tre colonne condivise fra
 * l'intestazione e tutte le righe, dichiarate una volta sola. */
.preview-panel {
    overflow: hidden;
    padding: 0;
    border-color: var(--color-ink-700);
    background-color: rgba(28, 25, 23, 0.8);
    color: #ffffff;
}

.preview-panel__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: 14px 20px;
    border-bottom: 1px solid var(--color-ink-700);
    font-weight: 600;
}

/* Il link non deve mai spezzarsi in modo da isolare la freccia su una riga
 * propria: resta un unico blocco, anche se cio' costringe lo spazio
 * disponibile a restringersi. */
.preview-panel__head .text-link {
    flex-shrink: 0;
    white-space: nowrap;
}

.preview-columns,
.preview-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 8rem 5rem;
    align-items: center;
    gap: 12px;
    padding-inline: 20px;
}

.preview-columns {
    padding-block: 10px;
    border-bottom: 1px solid var(--color-ink-700);
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-ink-400);
}

.preview-row {
    min-height: 60px;
    border-bottom: 1px solid var(--color-ink-800);
    font-size: 0.875rem;
}

.preview-row:last-child {
    border-bottom: 0;
}

.preview-row__name {
    font-weight: 500;
}

.preview-row__status {
    color: var(--color-ink-300);
}

.preview-columns > :last-child,
.preview-row > :last-child {
    justify-self: end;
    text-align: right;
    color: var(--color-ink-400);
}

/* --- Tabella dei repository: una vera <table>, cosi' le colonne sono
 * condivise per costruzione e restano allineate a qualunque contenuto. */
.table-scroll {
    overflow-x: auto;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-2xl);
    background-color: var(--color-surface-raised);
    /* Causa reale dello scroll orizzontale dell'intera pagina fra 760px e
     * 1024px (misurato: <html>.scrollWidth 32px oltre il viewport, anche se
     * .table-scroll clippa correttamente la <table> al suo interno): senza
     * un hint di contenimento esplicito, Chromium include comunque l'overflow
     * interno della tabella nel calcolo dello scrollWidth della radice del
     * documento. "contain: paint" dichiara che nulla di questo elemento
     * dipinge fuori dal suo padding-box, cosa gia' vera vista overflow-x:auto,
     * e ferma quella propagazione senza toccare <html>. */
    contain: paint;
}

.repo-table {
    width: 100%;
    min-width: 46rem;
    border-collapse: collapse;
    font-size: 0.9375rem;
}

.repo-table th,
.repo-table td {
    padding: 14px 20px;
    text-align: left;
    vertical-align: top;
}

.repo-table thead th {
    border-bottom: 1px solid var(--color-line);
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-fg-subtle);
    white-space: nowrap;
}

.repo-table tbody tr + tr th,
.repo-table tbody tr + tr td {
    border-top: 1px solid var(--color-line);
}

.repo-table .is-numeric {
    text-align: right;
}

.repo-table__name {
    font-weight: 600;
}

.repo-table__owner {
    display: block;
    color: var(--color-fg-subtle);
    font-family: var(--font-mono);
    font-size: 11px;
}

.repo-table__description {
    display: block;
    max-width: 40rem;
    margin-top: 4px;
    color: var(--color-fg-muted);
    font-size: 0.875rem;
    font-weight: 400;
}

.repo-table__link {
    color: var(--color-accent);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.repo-table__link:hover {
    text-decoration: underline;
    text-underline-offset: 4px;
}

.snapshot-note {
    margin: 12px 0 0;
    color: var(--color-fg-subtle);
    font-size: 0.8125rem;
}

/* ---------------------------------------------------------------- 09 ACCESSO
 * Le pagine di accesso all'area riservata (login, password dimenticata, link
 * monouso). Vivono sul sistema visivo pubblico — fondo ink, pannello marcato,
 * logo intero — perche' sono la prima cosa che il titolare vede: il CMS dietro
 * mantiene il suo foglio (`cms.css`).
 * -------------------------------------------------------------------------- */
.auth-body {
    display: grid;
    place-items: center;
    min-height: 100vh;
    padding: var(--space-3) var(--shell-gutter);
}

.auth-shell {
    display: grid;
    justify-items: center;
    gap: var(--space-3);
    width: min(30rem, 100%);
}

.auth-panel {
    width: 100%;
}

.auth-panel h1 {
    margin: 8px 0 0;
    font-size: clamp(1.5rem, 3vw, 1.875rem);
}

.auth-panel > p {
    margin: 12px 0 0;
    color: var(--color-fg-muted);
    font-size: 0.9375rem;
}

.auth-form {
    display: grid;
    gap: var(--space-2);
    margin-top: var(--space-3);
}

.auth-form label {
    display: grid;
    gap: 6px;
    font-size: 0.875rem;
    font-weight: 600;
}

.auth-form input {
    padding: 10px 12px;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius-md);
    background-color: var(--color-surface-sunken);
    color: var(--color-fg);
    font-family: inherit;
    font-size: 0.9375rem;
}

.auth-check {
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    font-weight: 400;
}

.auth-check input {
    width: auto;
}

/* Pulsanti omologhi: l'azione principale occupa sempre l'intera larghezza del
   pannello, cosi' login, reset e invito hanno lo stesso ingombro. */
.auth-form .button {
    width: 100%;
}

.auth-links {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-1) var(--space-2);
    margin: var(--space-2) 0 0;
    font-size: 0.875rem;
}

.auth-notice {
    margin: 0 0 var(--space-2);
    padding: 10px 12px;
    border: 1px solid var(--color-ok);
    border-radius: var(--radius-md);
    background-color: var(--color-ok-bg);
    color: var(--color-ok);
    font-size: 0.875rem;
}

.auth-hint {
    margin: 4px 0 0;
    color: var(--color-fg-subtle);
    font-size: 0.8125rem;
}

.auth-footer {
    margin: 0;
    font-size: 0.875rem;
}

/* Strada alternativa sotto il modulo (Google, passkey): divisore "oppure" e
   pulsante della stessa larghezza di quello principale. */
.auth-alternative {
    display: grid;
    gap: var(--space-1);
    margin-top: var(--space-2);
}

.auth-alternative[hidden] {
    display: none;
}

.auth-alternative .button {
    width: 100%;
}

.auth-alternative .field-error,
.auth-alternative .auth-hint {
    margin: 0;
}

.auth-divider {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: 12px;
    margin: 0;
    color: var(--color-fg-subtle);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.auth-divider::before,
.auth-divider::after {
    border-top: 1px solid var(--color-line-strong);
    content: '';
}

/* Riga di testo prima dei link in fondo al pannello (pagina del codice). */
.auth-panel > .auth-hint--section {
    margin-top: var(--space-3);
    font-size: 0.875rem;
}

/* Funzione non disponibile (recupero via email senza posta): lo si dice in
   un riquadro, invece di mostrare un modulo che non porterebbe a nulla. */
.auth-panel > .auth-warning {
    margin: var(--space-2) 0 0;
    padding: 10px 12px;
    border: 1px solid var(--color-warn);
    border-radius: var(--radius-md);
    background-color: var(--color-warn-bg);
    color: var(--color-warn);
    font-size: 0.875rem;
}

/* ------------------------------------------------------------- 10 RESPONSIVE
 * Sugli schermi stretti si degrada a righe etichetta-sinistra / valore-destra
 * a tutta larghezza, ma in modo COERENTE in tutta la vista.
 * -------------------------------------------------------------------------- */
@media (max-width: 1024px) {
    .hero-grid,
    .method-layout,
    .contact-panel {
        grid-template-columns: minmax(0, 1fr);
    }

    .method-intro {
        position: static;
    }

    .scenario-grid,
    .network-grid,
    .capability-grid,
    .feature-grid,
    .principle-grid,
    .article-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 760px) {
    :root {
        --shell-gutter: 16px;
    }

    .public-nav-desktop {
        display: none;
    }

    .mobile-nav {
        display: block;
    }

    .brand-logo--header {
        height: 36px;
    }

    .scenario-grid,
    .network-grid,
    .capability-grid,
    .feature-grid,
    .principle-grid,
    .article-grid,
    .claim-band .shell,
    .actions {
        grid-template-columns: minmax(0, 1fr);
    }

    .claim-band p {
        min-height: 64px;
        border-left: 0;
        border-top: 1px solid var(--color-line);
    }

    .claim-band p:first-child {
        border-top: 0;
    }

    .callout-inner,
    .contact-band-inner {
        flex-direction: column;
        align-items: flex-start;
    }

    /* Invito ai contatti a fondo articolo: sotto la frase invece che a fianco,
     * pulsante a tutta larghezza come negli altri gruppi di azioni (`.actions`). */
    .article-signature__cta {
        flex-direction: column;
        align-items: stretch;
    }

    .method-steps li,
    .service-list article,
    .service-use-cases li {
        grid-template-columns: 2.75rem minmax(0, 1fr);
        gap: 12px;
    }

    .footer-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Riga del titolare: una voce per riga, centrate come sopra; i punti
     * separatori resterebbero appesi a fine riga. */
    .footer-bottom {
        flex-direction: column;
        align-items: center;
    }

    .footer-separator {
        display: none;
    }

    /* Titolo e link del pannello anteprima su due righe allineate a
     * sinistra, invece di contendersi la stessa riga stretta. */
    .preview-panel__head {
        flex-direction: column;
        align-items: flex-start;
        gap: 6px;
    }

    /* Paginazione: riepilogo sopra, caselle sotto e centrate. */
    .pagination {
        flex-direction: column;
        align-items: stretch;
    }

    .pagination-pages {
        justify-content: center;
        overflow-x: auto;
    }

    /* La tabella dei repository degrada a blocchi impilati: niente scroll
     * orizzontale. Ogni riga diventa un blocco (nome/owner/descrizione in
     * testa) seguito da etichetta-sinistra/valore-destra su una griglia a
     * due colonne dichiarata una sola volta qui e condivisa da tutte le
     * celle, cosi' i valori restano incolonnati fra un repository e l'altro. */
    .table-scroll {
        overflow-x: visible;
        padding-inline: 20px;
    }

    .repo-table,
    .repo-table thead,
    .repo-table tbody,
    .repo-table tr,
    .repo-table th,
    .repo-table td {
        display: block;
        width: 100%;
        min-width: 0;
    }

    .repo-table thead {
        display: none;
    }

    .repo-table th,
    .repo-table td {
        padding: 0;
    }

    .repo-table tbody tr {
        padding: 16px 0;
        border-top: 1px solid var(--color-line);
    }

    .repo-table tbody tr:first-child {
        border-top: 0;
    }

    .repo-table tbody tr + tr th,
    .repo-table tbody tr + tr td {
        border-top: 0;
    }

    .repo-table__name {
        margin-bottom: 10px;
    }

    .repo-table td {
        display: grid;
        grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
        column-gap: 12px;
        padding: 8px 0;
        border-top: 1px solid var(--color-line);
        text-align: right;
    }

    .repo-table td::before {
        content: attr(data-label);
        font-family: var(--font-display);
        font-size: 11px;
        font-weight: 500;
        letter-spacing: 0.1em;
        text-transform: uppercase;
        text-align: left;
        color: var(--color-fg-subtle);
    }
}

/* ------------------------------------------------------ 11 MOVIMENTO RIDOTTO */
[data-reveal] {
    transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

[data-reveal].is-pending {
    opacity: 0;
    transform: translateY(16px);
}

[data-reveal].is-visible {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
        transition-duration: 0.01ms !important;
    }

    [data-reveal].is-pending {
        opacity: 1;
        transform: none;
    }
}
