/*
 * Pro Tennis — modern frontend.
 * Self-contained: no inline styles, no theme bleed expected.
 * Font: Geist (loaded by the plugin via wp_enqueue_style).
 *
 * MULTI-THEME COMPATIBILITY: every plugin container below is wrapped in
 * a defensive reset so themes that style * with weird line-heights, big
 * heading margins or default `display: list-item` etc. don't bleed in.
 * This is the "preventive reset" added 2026-05-03 — see memory file
 * `feedback_dev_multi_theme_compatibility.md` for the rationale.
 */

/* ============================================================
 * Defensive container reset.
 * Applied to every top-level plugin container so the surrounding
 * theme's CSS can't spill into our layout (large h1-h6 margins,
 * forced line-height, list bullets on stray <ul>, etc.).
 * Specific to plugin-owned classes: zero impact on theme content.
 * ============================================================ */
.pro-tennis-bracket,
.pro-tennis-tabs,
.pro-tennis-oop,
.pro-tennis-home,
.pro-tennis-albo,
.pt-torneo,
.pt-news-single,
.pt-news,
.pt-sponsor__grid,
.pt-infoboxes {
    box-sizing: border-box;
    line-height: 1.5;
}
.pro-tennis-bracket *,
.pro-tennis-bracket *::before,
.pro-tennis-bracket *::after,
.pro-tennis-tabs *,
.pro-tennis-tabs *::before,
.pro-tennis-tabs *::after,
.pro-tennis-oop *,
.pro-tennis-oop *::before,
.pro-tennis-oop *::after,
.pro-tennis-home *,
.pro-tennis-home *::before,
.pro-tennis-home *::after,
.pro-tennis-albo *,
.pro-tennis-albo *::before,
.pro-tennis-albo *::after,
.pt-torneo *,
.pt-torneo *::before,
.pt-torneo *::after,
.pt-news-single *,
.pt-news-single *::before,
.pt-news-single *::after,
.pt-news *,
.pt-news *::before,
.pt-news *::after {
    box-sizing: border-box;
}
/* Heading margins normalized inside our containers (themes often use
 * 2em+ margins on h1-h6 which break our compact layouts). The
 * news-single content area is excluded — there we WANT the theme
 * heading rhythm because it's reading-mode prose. */
.pro-tennis-bracket :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-tabs :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-oop :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-home :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-albo :is(h1,h2,h3,h4,h5,h6),
.pt-torneo > :not(.pt-news-single__content) :is(h1,h2,h3,h4,h5,h6) {
    margin-top: 0;
    margin-bottom: 0;
    line-height: 1.3;
}
/* Da v3.10.147: niente sillabazione automatica sui titoli dentro i
 * container del plugin. Alcuni temi WP applicano hyphens:auto globale
 * (testato in produzione TC Santa Croce 2026: "MON-DIALE" spezzato a
 * meta'). !important perche' il selettore tema potrebbe avere
 * specificita' alta (es. body h3.entry-title con hyphens:auto).
 * Da v3.10.148: aggiunti .pt-torneo (shell home torneo) e .pt-home
 * (sezioni news/sponsor/storia nella home) — il prefisso BEM .pt-home__*
 * non era coperto in modo esplicito dal selettore .pro-tennis-home,
 * e in produzione i titoli delle news in home torneo continuavano a
 * spezzarsi. */
.pt-news :is(h1,h2,h3,h4,h5,h6),
.pt-news-single :is(h1,h2,h3,h4,h5,h6),
.pt-torneo :is(h1,h2,h3,h4,h5,h6),
.pt-home :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-home :is(h1,h2,h3,h4,h5,h6),
.pro-tennis-albo :is(h1,h2,h3,h4,h5,h6),
.pt-home__news-title,
.pt-home__section-title {
    hyphens: none !important;
    -webkit-hyphens: none !important;
    -ms-hyphens: none !important;
}
/* Lists: themes sometimes set huge padding-left or unusual list-style.
 * Plugin lists are explicit (drinks bullets only when we want them). */
.pro-tennis-bracket ul, .pro-tennis-bracket ol,
.pro-tennis-tabs   ul, .pro-tennis-tabs   ol,
.pro-tennis-oop    ul, .pro-tennis-oop    ol,
.pro-tennis-home   ul, .pro-tennis-home   ol,
.pt-torneo > nav   ul, .pt-torneo > nav   ol {
    list-style: none;
    padding: 0;
    margin: 0;
}
/* Paragraphs reset: themes can set big bottom margins. We default to a
 * comfortable but compact spacing; specific places that need more room
 * override locally. Again: skip news prose, that wants reading rhythm. */
.pro-tennis-bracket p,
.pro-tennis-tabs   p,
.pro-tennis-oop    p,
.pro-tennis-home   p,
.pt-torneo > nav   p {
    margin: 0 0 8px;
}
/* Anchors inside our containers default to plain text-decoration: themes
 * often underline every <a> which clashes with our card layouts and tab
 * indicators. NOTE: we deliberately do NOT touch border-bottom here —
 * the plugin uses border-bottom semantically (round-tab active state,
 * news card hover bottom edge) so killing it caused regressions. */
.pro-tennis-bracket a,
.pro-tennis-tabs   a,
.pro-tennis-oop    a,
.pro-tennis-home   a,
.pro-tennis-albo   a,
.pt-torneo a:not(.pt-news-single__content a) {
    text-decoration: none;
    text-shadow: none;
}

/* Bandiere come <img> SVG Twemoji renderizzate lato server (vedi
 * ProTennis_Helpers::flag_img_html). !important per resistere a temi che
 * applicano border/border-radius/box-shadow a tutte le immagini nel content
 * (es. wrapper "thumbnail" dei builder come Aruba/divi/elementor).
 * Copre anche eventuali img.emoji generate da WP core / Twemoji JS. */
.pro-tennis-flag-img,
.pro-tennis-bracket img.pro-tennis-flag-img,
.pt-torneo        img.pro-tennis-flag-img,
.pro-tennis-home  img.pro-tennis-flag-img,
.pro-tennis-oop   img.pro-tennis-flag-img,
.pro-tennis-albo  img.pro-tennis-flag-img,
.pro-tennis-tabs  img.pro-tennis-flag-img,
.pro-tennis-bracket img.emoji,
.pt-torneo        img.emoji,
.pro-tennis-home  img.emoji,
.pro-tennis-oop   img.emoji,
.pro-tennis-albo  img.emoji,
.pro-tennis-tabs  img.emoji {
    height: 1em !important;
    width: auto !important;
    min-width: 1.3em !important;
    vertical-align: -0.15em !important;
    margin: 0 0.1em !important;
    display: inline-block !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    padding: 0 !important;
    object-fit: contain;
}

.pro-tennis-bracket {
    --pro-tennis-accent: #b01d1f;
    --pro-tennis-text: #1a1a1a;
    --pro-tennis-text-muted: #9ca3af;
    --pro-tennis-text-loser: #6b7280;
    --pro-tennis-border: #e5e7eb;
    --pro-tennis-bg: #ffffff;
    --pro-tennis-bg-winner: #f7f9f5;
    --pro-tennis-bg-tab: #f3f4f6;
    /* Da v3.10.82: chip LIVE sui match in corso riusa le var verdi
     * dell'OOP. Le devo definire anche qui altrimenti var() risolve
     * a transparent e la chip sembra scolorita. */
    --pro-tennis-live: #65a30d;
    --pro-tennis-live-bg: #ecfccb;

    max-width: 760px;
    margin: 0 auto;
    color: var(--pro-tennis-text);
    font-family: 'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-feature-settings: 'tnum' 1, 'lnum' 1, 'cv11' 1;
    font-size: 15px;
    line-height: 1.4;
    letter-spacing: -0.01em;
}
.pro-tennis-bracket *,
.pro-tennis-bracket *::before,
.pro-tennis-bracket *::after { box-sizing: border-box; }

/* -------- Official PDF button -------- */
.pro-tennis-pdf-button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    box-sizing: border-box;
    padding: 12px 18px;
    margin: 0 0 18px;
    background: #f3f4f6;
    color: var(--pro-tennis-text);
    border: 1px solid var(--pro-tennis-border);
    border-radius: 6px;
    text-decoration: none;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.02em;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease, transform .1s ease;
}
.pro-tennis-pdf-button:hover,
.pro-tennis-pdf-button:focus-visible {
    /* Lighter red than --pro-tennis-accent so the button feels approachable rather
     * than alarming and doesn't compete with the "active round" red below. */
    background: #ef4444;
    color: #fff;
    border-color: #ef4444;
    text-decoration: none;
}
.pro-tennis-pdf-button:active { transform: translateY(1px); }
.pro-tennis-pdf-button__icon { font-size: 16px; }

/* -------- Tournament tabs (multi-tournament edition shortcode) -------- */
.pro-tennis-tabs {
    --pro-tennis-accent: #b01d1f;
    --pro-tennis-text: #1a1a1a;
    --pro-tennis-text-muted: #9ca3af;
    --pro-tennis-text-loser: #6b7280;
    --pro-tennis-border: #e5e7eb;
    --pro-tennis-bg-tab: #f3f4f6;

    max-width: 760px;
    margin: 0 auto 18px;
    font-family: 'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    color: var(--pro-tennis-text);
    letter-spacing: -0.01em;
}
.pro-tennis-tabs__nav {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 18px;
    padding: 6px;
    background: #fafafa;
    border: 1px solid var(--pro-tennis-border);
    border-radius: 999px;
}
.pro-tennis-tabs__tab {
    flex: 1 1 auto;
    text-align: center;
    padding: 9px 18px;
    color: var(--pro-tennis-text-loser);
    background: transparent;
    border-radius: 999px;
    text-decoration: none;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: -0.005em;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease;
}
.pro-tennis-tabs__tab:hover {
    /* Soft pink tint on hover for inactive tabs (consistent with the OOP PDF
     * button: lighter than the brand red so the label stays readable). */
    background: #fee2e2;
    color: #b01d1f;
    text-decoration: none;
}
.pro-tennis-tabs__tab.is-active {
    background: #fee2e2;
    color: #b01d1f;
    box-shadow: 0 1px 2px rgba(176, 29, 31, 0.08);
}
.pro-tennis-tabs__tab.is-active:hover {
    background: #fecaca;
    color: #b01d1f;
}
.pro-tennis-tabs__panels { /* container */ }
.pro-tennis-tabs__panel[hidden] { display: none; }

@media (max-width: 540px) {
    .pro-tennis-tabs__nav { border-radius: 12px; padding: 4px; }
    .pro-tennis-tabs__tab { font-size: 13px; padding: 8px 12px; flex: 1 1 calc(50% - 6px); }
}

/* -------- "← Ordini di gioco" breadcrumb -------- */
.pro-tennis-back-link {
    display: inline-block;
    margin: 0 0 12px;
    color: var(--pro-tennis-text-muted, #9ca3af);
    font-family: 'Geist', system-ui, sans-serif;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    letter-spacing: -0.005em;
    transition: color .15s ease;
}
.pro-tennis-back-link:hover {
    color: var(--pro-tennis-accent, #b01d1f);
    text-decoration: none;
}

/* -------- Round tabs -------- */
.pro-tennis-rounds {
    margin: 0 0 18px;
    border-bottom: 1px solid var(--pro-tennis-border);
}
.pro-tennis-rounds ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.pro-tennis-rounds li { margin: 0; padding: 0; }
.pro-tennis-rounds a {
    display: block;
    padding: 10px 18px;
    color: var(--pro-tennis-text-muted);
    font-weight: 600;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.pro-tennis-rounds a:hover,
.pro-tennis-rounds a:focus-visible {
    color: var(--pro-tennis-text);
    background: var(--pro-tennis-bg-tab);
}
.pro-tennis-rounds .is-active a {
    color: var(--pro-tennis-accent);
    border-bottom-color: var(--pro-tennis-accent);
}
.pro-tennis-rounds .is-active a:hover { background: transparent; }

/* -------- Matches list -------- */
.pro-tennis-matches {
    list-style: none;
    margin: 0;
    padding: 0;
}
.pro-tennis-match {
    border-bottom: 1px solid var(--pro-tennis-border);
    padding: 6px 0;
    border-radius: 6px;
    transition: background-color .25s ease, box-shadow .25s ease;
    scroll-margin-top: 120px;
    /* relative per posizionare la chip LIVE assolutamente in alto a destra
     * (v3.10.81). Non altera il grid layout dei player rows. */
    position: relative;
}
/* Indicatore LIVE su match in corso (v3.10.86 — design su richiesta utente).
 *
 * Visual: chip pillola piccola con dot pulsante + scritta "LIVE", ruotata
 * 90° (text reads bottom-to-top), posizionata sul lato sinistro del match
 * card e centrata verticalmente fra i due giocatori. Niente padding-shift
 * sul match — la chip vive nel lato sinistro del flag column del player 1
 * sfiorandolo (occupazione minima visiva).
 *
 * La chip riusa .pro-tennis-oop__badge--live per i colori (background
 * pastello + dot verde pulsante). Il pulse del dot e' gia animato dalla
 * regola .pro-tennis-oop__live-dot esistente. */
.pro-tennis-match__live {
    position: absolute;
    top: 50%;
    left: 1px;
    /* translate(-50%, -50%) sposta il centro della chip a (left, top),
     * rotate(-90deg) la ruota di 90° CCW (LIVE leggibile dal basso). */
    transform: translate(-50%, -50%) rotate(-90deg);
    transform-origin: center center;
    z-index: 5;
    /* line-height 1 + padding-vertical 0 = altezza chip = altezza testo.
     * Dopo la rotazione l'altezza diventa lo "spessore" orizzontale della
     * chip sul bordo sinistro del match. Stretto = non si sovrappone al
     * contenuto su mobile (richiesta utente 2026-05-10). */
    font-size: 8px !important;
    line-height: 1 !important;
    padding: 0 5px !important;
    letter-spacing: 0.03em !important;
    box-shadow: 0 1px 3px rgba(101, 163, 13, 0.25);
    /* whitespace nowrap per evitare wrap della parola "LIVE" */
    white-space: nowrap;
}
.pro-tennis-match__live .pro-tennis-oop__live-dot {
    width: 4px !important;
    height: 4px !important;
    margin-right: 3px !important;
}
@media (max-width: 480px) {
    .pro-tennis-match__live {
        font-size: 7px !important;
        padding: 0 4px !important;
    }
}
.pro-tennis-match:first-child { border-top: 1px solid var(--pro-tennis-border); }
/* Brief flash when arriving via the OOP click-through: ?focus=<match_id> */
.pro-tennis-match.is-focus-flash {
    animation: pro-tennis-focus-flash 2.2s ease-out;
}
@keyframes pro-tennis-focus-flash {
    0%   { background: rgba(176, 29, 31, 0.18); box-shadow: 0 0 0 3px rgba(176, 29, 31, 0.55); }
    70%  { background: rgba(176, 29, 31, 0.10); box-shadow: 0 0 0 3px rgba(176, 29, 31, 0.25); }
    100% { background: transparent; box-shadow: 0 0 0 0 rgba(176, 29, 31, 0); }
}

/* -------- Player rows -------- */
.pro-tennis-player {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) 36px 36px 36px;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    color: var(--pro-tennis-text-loser);
    border-radius: 6px;
}
.pro-tennis-player.is-winner {
    color: var(--pro-tennis-text);
    background: var(--pro-tennis-bg-winner);
}

.pro-tennis-flag {
    font-size: 20px;
    line-height: 1;
    text-align: center;
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.pro-tennis-flag--inline {
    display: inline-block;
    font-size: 1em;
    margin-right: 1px;
    text-align: left;
    width: auto;
}

/* Doubles: hide the dedicated flag column; flags are inline within the name. */
.pro-tennis-bracket[data-doubles="1"] .pro-tennis-player {
    grid-template-columns: minmax(0, 1fr) 36px 36px 36px;
}
.pro-tennis-bracket[data-doubles="1"] .pro-tennis-player > .pro-tennis-flag:not(.pro-tennis-flag--inline) {
    display: none;
}
.pro-tennis-flag-fallback {
    display: inline-block;
    font-size: 10px;
    font-weight: 600;
    color: var(--pro-tennis-text-muted);
    border: 1px solid var(--pro-tennis-border);
    padding: 1px 4px;
    border-radius: 3px;
    font-family: inherit;
}

.pro-tennis-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 400;
}
.pro-tennis-player.is-winner .pro-tennis-name { font-weight: 600; }
/* Link cliccabile sul nome giocatore (solo dentro router): hover sottolineato
 * accent. Niente decorazione di base così il bracket resta pulito.
 *
 * !important + selettori a doppia classe per resistere a temi con regole
 * `body a:hover { color: X !important; text-decoration: underline !important }`
 * tipiche di builder (Aruba/tcsantacroce vs studio.progettoimmagina): senza
 * !important il colore accent dell'hover non passa e l'utente vede il colore
 * di default del tema. */
.pro-tennis-bracket a.pro-tennis-name-link,
.pt-torneo        a.pro-tennis-name-link {
    color: inherit !important;
    text-decoration: none !important;
    border-bottom: 1px dotted transparent !important;
    transition: color .12s ease, border-color .12s ease;
    cursor: pointer;
}
.pro-tennis-bracket a.pro-tennis-name-link:hover,
.pro-tennis-bracket a.pro-tennis-name-link:focus,
.pt-torneo        a.pro-tennis-name-link:hover,
.pt-torneo        a.pro-tennis-name-link:focus {
    color: var(--pro-tennis-accent, #b01d1f) !important;
    border-bottom-color: currentColor !important;
    text-decoration: none !important;
}

.pro-tennis-seed {
    color: var(--pro-tennis-text-muted);
    font-weight: 500;
    font-size: 0.72em;
    margin-left: 2px;
    vertical-align: super;
    line-height: 1;
}
.pro-tennis-empty { color: var(--pro-tennis-text-muted); }

.pro-tennis-tag {
    display: inline-block;
    font-size: 0.6em; /* piu' piccolo: era 0.7em */
    font-weight: 500; /* meno bold: era 600 */
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 1px 8px;
    border-radius: 999px; /* pasticca: era 3px */
    margin-left: 5px;
    vertical-align: 2px;
    background: #f3f4f6;
    color: var(--pro-tennis-text-muted);
    border: 0; /* niente bordo: meno invadente */
}
.pro-tennis-tag--ret {
    /* Toni piu' chiari per non rubare attenzione al risultato (rit. e'
     * info secondaria). Era #fef3c7 + #b45309 + bordo giallo. */
    color: #92400e;
    background: #fffbeb;
    border: 0;
}
/* Da v3.10.89: chip "Qualificato/a" sui giocatori entrati nel main draw
 * via le qualificazioni (entry_status = Q) o come Lucky Loser (LL).
 * Giallo sbiadito (yellow-100 background + yellow-900 text) come da
 * richiesta utente. La parola e' un filo piu' grande del default tag
 * (text-transform: none per leggibilita' della parola completa). */
.pro-tennis-tag--qualified {
    background: #fef9c3 !important;  /* yellow-100 sbiadito */
    color: #854d0e !important;        /* yellow-900 */
    text-transform: none !important;
    font-weight: 600 !important;
    font-size: 0.7em !important;
    padding: 1px 7px !important;
    letter-spacing: 0.01em !important;
    white-space: nowrap;
}
@media (max-width: 480px) {
    .pro-tennis-tag--qualified {
        font-size: 0.65em !important;
        padding: 1px 6px !important;
    }
}
/* Sulla pagina giocatore (h2 nome) la chip e' affianco al nome grande,
 * piu' generosa. Override del .pro-tennis-tag base per leggibilita'. */
.pt-player__qualified {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 10px;
    padding: 3px 10px;
    border-radius: 999px;
    background: #fef9c3;
    color: #854d0e;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0;
    text-transform: none;
    vertical-align: middle;
}
@media (max-width: 480px) {
    .pt-player__qualified {
        font-size: 11px;
        padding: 2px 8px;
        margin-left: 6px;
    }
}

.pro-tennis-score--wo {
    color: var(--pro-tennis-accent);
    font-weight: 700;
    letter-spacing: 0.04em;
    font-variant: small-caps;
}

.pro-tennis-score {
    text-align: center;
    color: var(--pro-tennis-text-muted);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
    font-size: 15px;
    position: relative;
}
.pro-tennis-player.is-winner .pro-tennis-score {
    color: var(--pro-tennis-text);
    font-weight: 600;
}
.pro-tennis-score sup {
    font-size: 0.7em;
    font-weight: 500;
    color: var(--pro-tennis-text-muted);
    top: -0.5em;
    /* Da v3.10.138: width 0 + overflow visible cosi' il sup non occupa
       spazio nel flow di .pro-tennis-score (text-align: center). Senza
       questo, "6" + "<sup>2</sup>" venivano centrati insieme, spingendo
       il "6" a sinistra rispetto alle altre celle senza apice. Cosi'
       il "6" resta centrato come gli altri numeri, e l'apice fluttua
       a destra di esso. */
    display: inline-block;
    width: 0;
    overflow: visible;
    margin-left: 0;
    /* piccolo nudge orizzontale per staccare leggermente l'apice dal 6 */
    padding-left: 1px;
}

/* -------- Mobile -------- */
@media (max-width: 540px) {
    .pro-tennis-bracket { font-size: 14px; }
    .pro-tennis-rounds a { padding: 9px 12px; font-size: 12px; }
    .pro-tennis-player {
        grid-template-columns: 24px minmax(0, 1fr) 30px 30px 30px;
        gap: 6px;
        padding: 7px 8px;
    }
    .pro-tennis-bracket[data-doubles="1"] .pro-tennis-player {
        grid-template-columns: minmax(0, 1fr) 30px 30px 30px;
    }
    .pro-tennis-flag { font-size: 17px; }
    .pro-tennis-score { font-size: 14px; }
}

/* -------- Print -------- */
@media print {
    .pro-tennis-bracket { font-size: 12px; }
    .pro-tennis-player { padding: 4px 6px; }
    .pro-tennis-rounds, .pro-tennis-rounds * { display: none; }
}

/* =====================================================
 * Order of Play (OOP) — frontend
 * =================================================== */

.pro-tennis-oop {
    --pro-tennis-accent: #b01d1f;
    --pro-tennis-text: #1a1a1a;
    --pro-tennis-text-muted: #9ca3af;
    --pro-tennis-text-loser: #6b7280;
    --pro-tennis-border: #e5e7eb;
    --pro-tennis-bg-tab: #f3f4f6;
    --pro-tennis-bg-done: #f3f4f6;
    --pro-tennis-live: #65a30d;
    --pro-tennis-live-bg: #ecfccb;

    max-width: 1100px;
    margin: 0 auto;
    color: var(--pro-tennis-text);
    font-family: 'Geist', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    font-size: 15px;
    line-height: 1.4;
    letter-spacing: -0.01em;
}
.pro-tennis-oop *,
.pro-tennis-oop *::before,
.pro-tennis-oop *::after { box-sizing: border-box; }

/* Defensive resets against theme bleed (link underline, dashed borders). */
.pro-tennis-oop a,
.pro-tennis-oop a:hover,
.pro-tennis-oop a:focus,
.pro-tennis-oop a:visited {
    text-decoration: none;
    border: none;
    box-shadow: none;
}
.pro-tennis-oop .pro-tennis-oop__match,
.pro-tennis-oop .pro-tennis-pdf-button {
    /* Theme often draws dashed underlines on inline links — kill it. */
    background-image: none !important;
    text-decoration: none !important;
}

.pro-tennis-oop--empty { padding: 24px; text-align: center; color: var(--pro-tennis-text-muted); }

/* Header / date picker */
.pro-tennis-oop__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin: 0 0 14px;
    flex-wrap: wrap;
}
.pro-tennis-oop__date-nav {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
}
.pro-tennis-oop__nav,
.pro-tennis-oop__nav:link,
.pro-tennis-oop__nav:visited,
.pro-tennis-oop__nav:hover,
.pro-tennis-oop__nav:focus,
.pro-tennis-oop__nav:active { text-decoration: none !important; border-bottom: 0 !important; box-shadow: none !important; }
.pro-tennis-oop__nav {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px; height: 36px;
    border-radius: 50%;
    background: var(--pro-tennis-bg-tab);
    color: var(--pro-tennis-text);
    font-size: 22px;
    line-height: 1;
    transition: background-color .15s ease, color .15s ease;
}
.pro-tennis-oop__nav:hover { background: var(--pro-tennis-accent); color: #fff; }
.pro-tennis-oop__nav--disabled { opacity: 0.35; pointer-events: none; }
/* Dropdown custom giornata (sostituisce <select> nativo, inconsistent
 * cross-browser nel rendering del pannello opzioni). */
.pt-oop-date { position: relative; flex: 1; min-width: 0; }
.pt-oop-date__btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    border: 1px solid var(--pro-tennis-border);
    border-radius: 8px;
    padding: 10px 14px;
    background: #fff;
    font-family: inherit;
    font-size: 17px;
    font-weight: 600;
    color: var(--pro-tennis-text);
    cursor: pointer;
    text-transform: capitalize;
    letter-spacing: -0.01em;
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
    text-align: center;
}
.pt-oop-date__btn:hover { border-color: var(--pro-tennis-accent); }
.pt-oop-date__btn:focus,
.pt-oop-date__btn[aria-expanded="true"] {
    outline: none;
    border-color: var(--pro-tennis-accent);
    box-shadow: 0 0 0 3px rgba(176, 29, 31, .12);
}
.pt-oop-date__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-oop-date__caret {
    flex: 0 0 auto;
    color: var(--pro-tennis-accent);
    font-size: 14px;
    line-height: 1;
    transition: transform .15s ease;
}
.pt-oop-date__btn[aria-expanded="true"] .pt-oop-date__caret { transform: rotate(180deg); }

.pt-oop-date__panel {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 100;
    background: #fff;
    border: 1px solid var(--pro-tennis-border);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(15, 23, 42, .15), 0 2px 6px rgba(15, 23, 42, .08);
    list-style: none;
    margin: 0;
    padding: 6px;
    max-height: 320px;
    overflow-y: auto;
}
.pt-oop-date__panel[hidden] { display: none; }

.pt-oop-date__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 6px;
    font-size: 15px;
    font-weight: 500;
    color: var(--pro-tennis-text);
    cursor: pointer;
    text-transform: capitalize;
    transition: background-color .12s ease, color .12s ease;
    user-select: none;
}
.pt-oop-date__item:hover,
.pt-oop-date__item.is-active {
    background: var(--pro-tennis-accent);
    color: #fff !important;
}
.pt-oop-date__item.is-selected {
    background: rgba(176, 29, 31, .08);
    font-weight: 700;
}
.pt-oop-date__item.is-selected:hover,
.pt-oop-date__item.is-selected.is-active {
    background: var(--pro-tennis-accent);
    color: #fff !important;
}
.pt-oop-date__check {
    flex: 0 0 16px;
    text-align: center;
    font-weight: 700;
    color: var(--pro-tennis-accent);
    line-height: 1;
}
.pt-oop-date__item:hover .pt-oop-date__check,
.pt-oop-date__item.is-active .pt-oop-date__check { color: #fff; }
.pt-oop-date__item-label { flex: 1; }
.pro-tennis-oop__generated {
    font-size: 12px;
    color: var(--pro-tennis-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* ============================================================
 * Tournament home ([pro-tennis-tournament-home])
 * Three landing tiles + LIVE banner with three states. Designed
 * to share the brand palette already used by the rest of the
 * frontend so the shortcode blends in without theme tweaks.
 * ============================================================ */
.pro-tennis-home {
    font-family: 'Geist', system-ui, sans-serif;
    max-width: 1100px;
    margin: 0 auto;
    /* Da v3.10.163: overflow-x applicato solo su mobile via media
     * query qui sotto (vedi commento .pt-torneo per il razionale). */
    box-sizing: border-box;
}
@media (max-width: 820px) {
    .pro-tennis-home { overflow-x: hidden; }
}
.pro-tennis-home img { max-width: 100%; height: auto; }
body .pro-tennis-home > h3.pro-tennis-home__title,
body .pro-tennis-home h3.pro-tennis-home__title {
    text-align: left !important;
    color: #b01d1f !important;
    font-weight: 700 !important;
    letter-spacing: -0.01em;
    margin: 0 0 28px !important;
    padding: 0 0 18px !important;
    border-bottom: 0 !important;
}

/* Match block (live/today/tomorrow/upcoming): heading + 4-card grid */
.pro-tennis-home__matchblock { margin: 0 0 28px; }
.pro-tennis-home__matchblock-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    margin: 0 0 12px; font-size: 17px; letter-spacing: 0.01em;
    color: var(--pro-tennis-text);
}
.pro-tennis-home__matchblock-title { font-weight: 700; }
.pro-tennis-home__matchblock-icon { font-size: 18px; line-height: 1; }
.pro-tennis-home__matchblock-sub { font-size: 13px; color: #6b7280; font-weight: 500; }
.pro-tennis-home__live-dot {
    display: inline-block; width: 10px; height: 10px;
    background: #16a34a; border-radius: 50%;
    box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.6);
    animation: pro-tennis-home-pulse 1.4s infinite;
}
@keyframes pro-tennis-home-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.6); }
    70%  { box-shadow: 0 0 0 10px rgba(22, 163, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}
.pro-tennis-home__matchcards {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
}
.pro-tennis-home__matchcards .pro-tennis-oop__match { min-height: 150px; }
/* Court group: piccola etichetta del campo sopra al match-card sulla home */
.pro-tennis-home__court-group { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pro-tennis-home__court-group .pro-tennis-oop__match { width: 100%; min-height: 150px; }

/* Da v3.10.140: quando .pro-tennis-home__matchcards contiene il grid
 * OOP (.pro-tennis-home__live-grid), disabilito il grid esterno a 4
 * colonne. Il grid interno gestisce le colonne dei court e lo scroll
 * orizzontale per >4 campi (stesso sistema di OOP completa). Senza
 * questa regola il grid annidato veniva schiacciato in una sola cella
 * della 4-col grid esterna. */
.pro-tennis-home__matchcards:has(> .pro-tennis-oop__scroll-wrap),
.pro-tennis-home__matchcards:has(> .pro-tennis-home__live-grid) {
    display: block;
    grid-template-columns: none;
    padding: 0;
    margin: 0;
}
/* Il grid OOP usa <section class="pro-tennis-oop__court"> con
 * display: contents — perfetto per ereditare le colonne. La match
 * card all'interno ha gia' min-height 150px via la regola
 * .pro-tennis-home__matchcards .pro-tennis-oop__match qui sopra
 * (selector ancestor, funziona anche col grid annidato). */

/* Da v3.10.141: scroll fade (sfumatura bianca) sul lato destro del grid
 * OOP per indicare visivamente che c'e' overflow orizzontale (scrollare
 * per vedere il resto). Mostrato solo quando il grid ha overflow E lo
 * scroll NON e' alla fine (JS gestisce le classi via initScrollFade).
 *
 * Da v3.10.142: rinominato a .pro-tennis-oop__fade (era .home__scroll-cue)
 * e applicato sia a home torneo sia a OOP completa. Tolto il chevron —
 * la freccia faceva pensare a un elemento cliccabile. La sola sfumatura
 * suggerisce di scorrere senza ambiguita'. */
.pro-tennis-oop__scroll-wrap {
    position: relative;
}
.pro-tennis-oop__fade {
    position: absolute;
    top: 0;
    right: 0;
    /* Da v3.10.143: bottom 22px (era 14) per coprire SOLO l'area card,
     * stando totalmente sopra la scrollbar custom (10px scrollbar + 18px
     * padding-bottom del grid = bottom 18-22 sicuro). */
    bottom: 22px;
    width: 80px;
    pointer-events: none;
    z-index: 9;
    background: linear-gradient(
        to right,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.85) 55%,
        rgba(255, 255, 255, 1) 100%
    );
    opacity: 1;
    transition: opacity 0.25s ease;
}
.pro-tennis-oop__fade.is-hidden {
    opacity: 0;
}
/* Screenshot mode: la fade non deve apparire nello screenshot (siamo
 * in modalita' "vedi tutti i campi affiancati" → niente piu' overflow
 * quindi anche niente fade). is-screenshotting copre il caso edge in
 * cui per qualche frame iniziale la fade era visibile prima del resize
 * del clone. */
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__fade {
    display: none;
}
.pro-tennis-home__court-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--pro-tennis-accent);
    padding: 4px 0 0 2px;
    line-height: 1.2;
}
.pro-tennis-home__matchblock-cta {
    display: inline-block; margin-top: 12px;
    font-size: 13px; font-weight: 600;
    color: var(--pro-tennis-accent); text-decoration: none;
    border-bottom: 1px dashed currentColor; padding-bottom: 1px;
}
.pro-tennis-home__matchblock-cta:hover { opacity: 0.85; text-decoration: none; }
@media (max-width: 980px) {
    .pro-tennis-home__matchcards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
    /* Mobile: scroll orizzontale snap. Card a ~82% del viewport così si
     * intravede la successiva (hint visivo "ce ne sono altre, swipe"). Le
     * card sono al massimo 4 (max-court-groups in render_matchgrid), quindi
     * lo scroll è sempre breve. */
    .pro-tennis-home__matchcards {
        display: flex;
        grid-template-columns: none;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
        gap: 10px;
        padding: 2px 16px 8px 2px; /* hint visivo dx */
        margin: 0 -16px 0 0; /* compensa il padding-right per centrare visivamente */
    }
    .pro-tennis-home__matchcards::-webkit-scrollbar { display: none; }
    .pro-tennis-home__matchcards > .pro-tennis-home__court-group,
    .pro-tennis-home__matchcards > .pro-tennis-oop__match {
        flex: 0 0 82%;
        max-width: 82%;
        scroll-snap-align: start;
    }
}

/* Text-only banner (pending/waiting/concluded info row) */
.pro-tennis-home__banner {
    display: flex; flex-direction: column; gap: 8px;
    padding: 16px 20px; border-radius: 14px; margin: 0 0 22px;
    border: 1px solid transparent;
}
.pro-tennis-home__banner.is-state-pause {
    background: #f8fafc; border-color: #e2e8f0; color: #334155;
}
.pro-tennis-home__banner-head {
    display: flex; align-items: center; gap: 10px;
    font-size: 17px; letter-spacing: 0.01em;
}
.pro-tennis-home__banner-icon { font-size: 20px; line-height: 1; }
.pro-tennis-home__banner-sub { font-size: 14px; opacity: 0.85; }
.pro-tennis-home__banner-cta {
    display: inline-block; align-self: flex-start;
    margin-top: 6px; font-size: 13px; font-weight: 600;
    color: inherit; text-decoration: none; opacity: 0.85;
    border-bottom: 1px dashed currentColor; padding-bottom: 1px;
}
.pro-tennis-home__banner-cta:hover { opacity: 1; text-decoration: none; }

/* Concluded — winners podium (4 cards, one per main category) */
.pro-tennis-home__winnersblock { margin: 0 0 28px; }
.pro-tennis-home__winnersblock-head {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    background: linear-gradient(180deg, #fefce8 0%, #fef3c7 100%);
    border: 1px solid #fbbf24; color: #78350f;
    padding: 12px 16px; border-radius: 12px;
    font-size: 16px; margin-bottom: 14px;
}
.pro-tennis-home__winnersblock-icon { font-size: 22px; line-height: 1; }
.pro-tennis-home__winnersblock-sub { font-size: 13px; opacity: 0.8; font-weight: 500; }
.pro-tennis-home__podium {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
}
.pro-tennis-home__podium-card {
    background: #fff; border: 1px solid #e5e7eb; border-radius: 12px;
    padding: 16px 14px; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.05);
    display: flex; flex-direction: column; gap: 10px;
}
.pro-tennis-home__podium-cat {
    font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
    text-transform: uppercase; color: #92400e;
}
.pro-tennis-home__podium-winner {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    font-size: 16px; font-weight: 700; color: #1e293b;
}
.pro-tennis-home__podium-trophy { font-size: 18px; line-height: 1; }
.pro-tennis-home__podium-flag { font-size: 18px; line-height: 1; }
.pro-tennis-home__podium-flag-sm { font-size: 14px; line-height: 1; }
.pro-tennis-home__podium-name { word-break: break-word; }
.pro-tennis-home__podium-score {
    font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums;
    color: #b45309; padding-top: 2px; border-top: 1px dashed #fde68a; padding-top: 8px;
}
.pro-tennis-home__podium-runner {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: 12.5px; color: #64748b; margin-top: -2px;
}
.pro-tennis-home__podium-runner-name { font-weight: 500; }
.pro-tennis-home__podium-runner-tag { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; opacity: 0.7; }
@media (max-width: 980px) {
    .pro-tennis-home__podium { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
    .pro-tennis-home__podium { grid-template-columns: 1fr; }
}

/* Tiles */
.pro-tennis-home__tiles {
    display: grid; gap: 18px;
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
.pro-tennis-home__tile {
    background: #f9fafb;
    border: 1px solid var(--pro-tennis-border);
    border-radius: 14px;
    padding: 28px 18px;
    text-align: center;
    text-decoration: none !important;
    color: var(--pro-tennis-text);
    display: flex; flex-direction: column; align-items: center; gap: 14px;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease, background-color .15s ease;
}
.pro-tennis-home__tile,
.pro-tennis-home__tile:hover,
.pro-tennis-home__tile:focus,
.pro-tennis-home__tile:active,
.pro-tennis-home__tile *,
.pro-tennis-home__tile:hover * { text-decoration: none !important; border-bottom: 0; }
.pro-tennis-home__tile.is-clickable { cursor: pointer; }
.pro-tennis-home__tile.is-clickable:hover {
    transform: translateY(-2px);
    border-color: var(--pro-tennis-accent);
    background: #ffffff;
    box-shadow: 0 6px 20px rgba(176, 29, 31, 0.10), 0 2px 6px rgba(15, 23, 42, 0.06);
    color: var(--pro-tennis-text);
}
.pro-tennis-home__tile-icon {
    width: 140px; height: 140px;
    display: flex; align-items: center; justify-content: center;
}
.pro-tennis-home__tile-icon img { max-width: 100%; max-height: 100%; object-fit: contain; }
.pro-tennis-home__tile-emoji { font-size: 88px; line-height: 1; }
.pro-tennis-home__tile-label {
    font-size: 16px; font-weight: 700; letter-spacing: -0.005em;
    text-transform: uppercase; color: var(--pro-tennis-text);
}

@media (max-width: 720px) {
    .pro-tennis-home__tiles { grid-template-columns: 1fr; }
    .pro-tennis-home__tile { padding: 22px 14px; }
    .pro-tennis-home__tile-icon { width: 110px; height: 110px; }
    .pro-tennis-home__tile-emoji { font-size: 72px; }
}

/* ============================================================
 * Albo d'oro ([pro-tennis-albo-oro])
 * Tabbed view of historical winners + auto-derived rows from
 * the tournaments managed by this plugin. Visual style mirrors
 * the brackets tabs so the page feels coherent across sections.
 * ============================================================ */
.pro-tennis-albo { font-family: 'Geist', system-ui, sans-serif; max-width: 900px; margin: 0 auto; }
.pro-tennis-albo__tabs {
    display: flex; flex-wrap: wrap; gap: 6px;
    background: #fafafa; border: 1px solid var(--pro-tennis-border);
    border-radius: 999px; padding: 6px; margin: 0 0 18px;
}
.pro-tennis-albo__tab {
    flex: 1 1 auto; min-width: 0; text-align: center;
    background: transparent; border: 0; cursor: pointer;
    padding: 9px 16px; border-radius: 999px;
    font-family: inherit; font-weight: 600; font-size: 14px;
    color: var(--pro-tennis-text-loser);
    transition: background-color .15s ease, color .15s ease;
}
.pro-tennis-albo__tab:hover { background: #fee2e2; color: #b01d1f; }
.pro-tennis-albo__tab.is-active { background: #fee2e2; color: #b01d1f; box-shadow: 0 1px 2px rgba(176, 29, 31, 0.08); }
.pro-tennis-albo__panel[hidden] { display: none; }
.pro-tennis-albo__table {
    width: 100%; border-collapse: collapse; font-size: 14px;
    table-layout: fixed;
}
.pro-tennis-albo__table thead th {
    text-align: left; font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--pro-tennis-text-muted);
    padding: 10px 12px; border-bottom: 2px solid #cbd5e1;
}
.pro-tennis-albo__table thead th:first-child { width: 80px; }
.pro-tennis-albo__table thead th:nth-child(2),
.pro-tennis-albo__table thead th:nth-child(3) { width: calc((100% - 80px) / 2); }
.pro-tennis-albo__table tbody td {
    padding: 10px 12px; border-bottom: 1px solid #d1d5db;
    vertical-align: top;
    word-wrap: break-word;
    overflow-wrap: break-word;
}
.pro-tennis-albo__table tbody tr:hover td { background: #fafafa; }
.pro-tennis-albo__year { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--pro-tennis-text); }
.pro-tennis-albo__winner strong { color: var(--pro-tennis-text); }
.pro-tennis-albo__runner { color: var(--pro-tennis-text-loser); }
.pro-tennis-albo__note { color: var(--pro-tennis-text-muted); font-size: 12px; font-style: italic; margin-left: 4px; }
@media (max-width: 540px) {
    /* Tabs scroll horizontally on mobile (instead of wrapping into 2 rows) —
     * matches the bracket-rounds + OOP-filters behavior. */
    .pro-tennis-albo__tabs {
        border-radius: 999px;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .pro-tennis-albo__tabs::-webkit-scrollbar { display: none; }
    .pro-tennis-albo__tab {
        font-size: 13px; padding: 8px 14px;
        flex: 0 0 auto;
        white-space: nowrap;
    }
    .pro-tennis-albo__table { font-size: 13px; }
    .pro-tennis-albo__table thead th, .pro-tennis-albo__table tbody td { padding: 8px; }
}

/* Live indicator pulse dot — kept for the per-card LIVE badge after the
 * "Adesso in campo" header banner was removed (the badge is enough). */
.pro-tennis-oop__live-dot {
    display: inline-block;
    width: 8px; height: 8px;
    background: #65a30d;
    border-radius: 50%;
    margin-right: 6px;
    box-shadow: 0 0 0 0 rgba(101, 163, 13, 0.7);
    animation: pro-tennis-oop-pulse 1.6s infinite;
}
@keyframes pro-tennis-oop-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(101, 163, 13, 0.6); }
    70%  { box-shadow: 0 0 0 8px rgba(101, 163, 13, 0); }
    100% { box-shadow: 0 0 0 0 rgba(101, 163, 13, 0); }
}

/* Filters */
.pro-tennis-oop__filters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin: 0 0 16px;
}
.pro-tennis-oop__filter {
    border: 1px solid var(--pro-tennis-border);
    background: #fff;
    color: var(--pro-tennis-text-loser);
    padding: 6px 14px;
    border-radius: 99px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.pro-tennis-oop__filter:hover { background: var(--pro-tennis-bg-tab); }
.pro-tennis-oop__filter.is-active {
    background: var(--pro-tennis-accent);
    color: #fff;
    border-color: var(--pro-tennis-accent);
}

/* Filtro "LIVE" — pinnato a destra (margin-left:auto), bordo rosso, dot
 * pulsante. Quando è attivo (cliccato) prende lo stile della .is-active
 * standard (background rosso, testo bianco). Renderizzato solo se ci
 * sono partite live in questo momento. */
.pro-tennis-oop__filter--live {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border-color: var(--pro-tennis-accent);
    color: var(--pro-tennis-accent);
}
.pro-tennis-oop__filter--live:hover {
    background: rgba(176, 29, 31, 0.08);
}
.pro-tennis-oop__filter--live.is-active .pro-tennis-oop__filter-livedot {
    background: #fff;
    box-shadow: 0 0 0 0 rgba(255, 255, 255, .9);
}
.pro-tennis-oop__filter-livedot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--pro-tennis-accent);
    animation: pt-oop-live-pulse 1.6s ease-out infinite;
}
@keyframes pt-oop-live-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(176, 29, 31, .55); }
    70%  { box-shadow: 0 0 0 6px rgba(176, 29, 31, 0); }
    100% { box-shadow: 0 0 0 0 rgba(176, 29, 31, 0); }
}
.pro-tennis-oop__filter-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    padding: 0 5px;
    height: 18px;
    border-radius: 99px;
    background: rgba(176, 29, 31, 0.12);
    color: var(--pro-tennis-accent);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}
.pro-tennis-oop__filter--live.is-active .pro-tennis-oop__filter-count {
    background: rgba(255, 255, 255, 0.22);
    color: #fff;
}

/* Bottone "Salva immagine" (admin only): genera un PNG dell'OOP via
 * html2canvas. Stile come gli altri filtri ma con accent diverso per
 * distinguerlo (e' un'azione, non un filtro). */
.pro-tennis-oop__screenshot {
    border: 1px solid var(--pro-tennis-border);
    background: #fff;
    color: var(--pro-tennis-text);
    border-radius: 999px;
    padding: 8px 14px;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s, border-color .15s;
}
.pro-tennis-oop__screenshot:hover:not(:disabled) {
    background: var(--pro-tennis-bg-tab);
    border-color: var(--pro-tennis-text-muted);
}
.pro-tennis-oop__screenshot:disabled {
    opacity: 0.6;
    cursor: wait;
}
/* Durante lo screenshot nascondi i bottoni interattivi (la barra filtri
 * intera, gli arrow di navigazione data, le freccettine cliccabili nelle
 * card) cosi l'immagine risulta pulita con solo il titolo data + i
 * match. La classe .is-screenshotting viene applicata da JS al clone
 * usato per html2canvas (vedi initOOPScreenshot). */
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__filters,
.pro-tennis-oop.is-screenshotting .pt-oop-date__nav,
.pro-tennis-oop.is-screenshotting .pro-tennis-pdf-button,
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__cta,
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__screenshot,
/* Da v3.10.132: nascondi anche elementi UI non rilevanti nello screenshot */
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__scroll-hint,
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__date-nav,
.pro-tennis-oop.is-screenshotting .pt-oop-date__caret,
.pro-tennis-oop.is-screenshotting .pt-oop-date__panel {
    display: none !important;
}
/* Date come testo centrato pulito: niente bordo, niente background,
 * niente shadow. Solo il label esposto.  v3.10.132 */
.pro-tennis-oop.is-screenshotting .pt-oop-date {
    display: block !important;
    text-align: center !important;
    margin: 0 0 16px !important;
}
.pro-tennis-oop.is-screenshotting .pt-oop-date__btn {
    display: inline !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    font-weight: 700 !important;
    font-size: 18px !important;
    color: #1f2937 !important;
    cursor: default !important;
}
.pro-tennis-oop.is-screenshotting .pt-oop-date__label {
    flex: none !important;
    overflow: visible !important;
    white-space: normal !important;
}
/* Margine interno durante lo screenshot: i contenuti non devono toccare
 * il bordo dell'immagine — bastano 10px per lato + un filo sopra/sotto.
 * Il background bianco lo mette html2canvas (backgroundColor:'#ffffff'). */
.pro-tennis-oop.is-screenshotting {
    padding: 10px !important;
    box-sizing: border-box;
}
/* v3.10.64: nello screenshot le bandiere usano l'aspect ratio NATURALE
 * dell'SVG (square 36x36 di twemoji) invece che il box rettangolare
 * 1em x 1.3em del live. La regola di default `min-width: 1.3em` sulla
 * .pro-tennis-oop img.emoji costringe le bandiere in un rettangolo
 * landscape, e siccome il twemoji SVG e' quadrato, il contenuto della
 * bandiera viene visivamente stirato — appare schiacciata.
 *
 * Override solo nel clone (is-screenshotting): min-width 0, larghezza
 * automatica dall'aspect intrinsic della PNG rasterizzata (square).
 * Risultato: bandiere quadrate 1em x 1em, proporzioni corrette. La
 * pagina live resta com'e' (la richiesta utente era di non toccarla). */
.pro-tennis-oop.is-screenshotting img.emoji,
.pro-tennis-oop.is-screenshotting img[src*="twemoji"],
.pro-tennis-oop.is-screenshotting img[src*="jsdelivr.net/gh/twitter"] {
    min-width: 0 !important;
    width: auto !important;
    height: 1em !important;
    object-fit: contain !important;
}
/* v3.10.69-70: lo screenshot ora preserva il layout grid del live (stesso
 * ordine court, stessi placeholder leading/trailing, stesso allineamento
 * per slot) ma con un paio di refinement per rendere la card meno
 * verticale e quindi l'OOP complessivo meno lungo:
 *   - Nascondiamo le chip di stato (LIVE + CONCLUSO): UI dynamic in static
 *     non aggiungono info che lo screenshot non abbia gia (lo score nelle
 *     card concluse mostra il risultato, non serve la chip CONCLUSO; la
 *     chip LIVE animata persa la sua semantica in immagine).
 *   - Collassiamo il match-bot a 0 (non c'e' piu' niente dentro: chip
 *     nascoste + cta blu nascosto = riga vuota).
 *   - Rimuoviamo il min-height 130px dalle card e dalle righe del grid:
 *     ogni slot row si dimensiona alla card piu' alta del proprio slot,
 *     niente piu' "spazio morto" sotto le card piu' corte. */
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__badge--live,
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__badge--done {
    display: none !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__match-bot {
    min-height: 0 !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__match {
    min-height: 0 !important;
    /* v3.10.73: compressione spazi interni per accorciare l'OOP
     * verticalmente senza sacrificare la leggibilita. La font-size dei
     * nomi resta invariata; riduciamo padding card, padding players
     * (la zona centrale con i nomi), margin del separator vs, e gap
     * della griglia. Saving stimato ~30px per card x N slot. */
    padding: 6px 10px !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__players {
    padding: 2px 4px !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__separator {
    margin: 1px 0 !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__score-line {
    margin-top: 2px !important;
}
.pro-tennis-oop.is-screenshotting .pro-tennis-oop__grid {
    gap: 6px !important;
}
/* Nota: l'override del grid-template-rows non puo' essere fatto in CSS
 * perche' rompe il count di righe esplicite (con grid-auto-flow: column,
 * ridurre a 1 riga manda ogni card in una colonna implicita propria —
 * layout esploso a N colonne sottili). Lo facciamo via JS sul clone in
 * initOOPScreenshot — vedi assets/frontend.js. */

/* Grid: column-major flow so every "row" is a slot index. Each court contributes
 * its header + N slot cells via display:contents, which lets grid-auto-rows
 * align cards across courts at equal heights (the tallest card on a row sets
 * the row height for all the others). The PHP renderer passes
 * grid-template-rows inline ("auto" for the header row, then N x 1fr for
 * slot rows) so this is robust regardless of slot count. */
.pro-tennis-oop__grid {
    display: grid;
    gap: 12px;
    grid-auto-flow: column;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    /* Da v3.10.121: scroll orizzontale per OOP con > 4 court (es. giorno
     * dei doppi: 6-7 court con balloon). Il PHP imposta min-width 220px
     * per colonna in quel caso; qui l'overflow attiva la scrollbar.
     * Da v3.10.122: scrollbar custom sempre visibile + cursor grab per
     * indicare che il grid e' trascinabile (JS aggiunge l'handler).
     * Da v3.10.143: padding-bottom 18px per staccare le card dalla
     * scrollbar (su macOS Chrome la scrollbar e' overlay e si sovrapponeva
     * agli angoli inferiori delle card, coprendo CTA + chip LIVE). Il
     * padding sposta le card su; la scrollbar resta in fondo al grid.
     */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 18px;
    /* Scrollbar custom — chiaramente visibile su Chrome/Safari */
    scrollbar-width: thin;
    scrollbar-color: var(--tcsc-accent, #b01d1f) #f3f4f6;
}
.pro-tennis-oop__grid::-webkit-scrollbar {
    height: 10px;
    background: #f3f4f6;
}
.pro-tennis-oop__grid::-webkit-scrollbar-thumb {
    background: var(--tcsc-accent, #b01d1f);
    border-radius: 5px;
    border: 2px solid #f3f4f6;
}
.pro-tennis-oop__grid::-webkit-scrollbar-thumb:hover {
    background: #8a1518;
}
/* Cursor "grab" quando il grid e' scrollabile (JS attiva la classe).
 * Da v3.10.128: blocco anche il native drag-and-drop dei link e la
 * selezione testo. Senza questo, il browser inizia un drag-image quando
 * l'utente preme il mouse su una card-link, e il nostro tracking dei
 * mousemove si rompe (native drag prende il sopravvento). */
.pro-tennis-oop__grid.is-draggable {
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
}
.pro-tennis-oop__grid.is-draggable a,
.pro-tennis-oop__grid.is-draggable img {
    -webkit-user-drag: none;
    -khtml-user-drag: none;
    -moz-user-drag: none;
    -o-user-drag: none;
    user-drag: none;
}
.pro-tennis-oop__grid.is-dragging {
    cursor: grabbing;
}
/* Hint visuale "swipe →" sopra al grid quando ce' overflow (mostrato
 * solo i primi 5 secondi via JS che rimuove la classe dopo timeout) */
.pro-tennis-oop__scroll-hint {
    display: none;
    font-size: 12px;
    color: var(--tcsc-accent, #b01d1f);
    background: rgba(176, 29, 31, 0.08);
    padding: 6px 10px;
    border-radius: 6px;
    margin: 0 0 8px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-align: center;
}
.pro-tennis-oop.has-scroll-hint .pro-tennis-oop__scroll-hint {
    display: block;
}
.pro-tennis-oop__grid[data-courts="1"] { grid-template-columns: 1fr; }
.pro-tennis-oop__grid[data-courts="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pro-tennis-oop__grid[data-courts="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pro-tennis-oop__grid[data-courts="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.pro-tennis-oop__grid[data-courts="5"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.pro-tennis-oop__grid[data-courts="6"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }

.pro-tennis-oop__court {
    display: contents;
    min-width: 0;
}
.pro-tennis-oop__court-name {
    text-align: center;
    font-weight: 700;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 6px 0;
    background: var(--pro-tennis-bg-tab);
    border-radius: 6px;
    color: var(--pro-tennis-text-loser);
}
.pro-tennis-oop__empty { min-height: 60px; height: 100%; }
/* Placeholder card per slot vuoto in court che inizia piu' tardi (es.
 * Villanova alle 13:00 quando i Balloon iniziano alle 09:00). Stesso
 * footprint di una match card ma con bordo tratteggiato + freccia in
 * giu' centrata che suggerisce "le partite di questo campo sono piu'
 * sotto" — richiesta utente 2026-05-10. */
.pro-tennis-oop__empty--placeholder {
    min-height: 130px;
    border: 1px dashed var(--pro-tennis-border);
    border-radius: 10px;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* Trailing empty: il court ha terminato il suo programma. Niente bordo,
 * niente freccia — solo cella trasparente che mantiene l'allineamento
 * del grid coi court che hanno ancora match nei slot successivi. */
.pro-tennis-oop__empty--trailing {
    border: 0 !important;
    background: transparent !important;
}
.pro-tennis-oop__empty-arrow {
    font-size: 28px;
    line-height: 1;
    color: var(--pro-tennis-text-muted);
    opacity: 0.5;
    /* leggera animazione per attirare l'occhio sul "scorri giu" */
    animation: pt-oop-arrow-bob 2.4s ease-in-out infinite;
}
@keyframes pt-oop-arrow-bob {
    0%, 100% { transform: translateY(0);   opacity: 0.5; }
    50%      { transform: translateY(4px); opacity: 0.8; }
}

/* Match cards: 4-corner layout with centered players in the middle.
 * height:100% lets grid stretch every card on a row to the same height as the
 * tallest one (so doubles names + "or X" alternative don't make neighbors look
 * misaligned). */
.pro-tennis-oop .pro-tennis-oop__match {
    display: flex;
    flex-direction: column;
    background: #ffffff !important;
    border: 1px solid #e5e7eb !important;
    border-radius: 10px;
    padding: 10px 12px;
    text-decoration: none;
    color: inherit;
    min-height: 130px;
    height: 100%;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 2px 4px rgba(15, 23, 42, 0.03) !important;
    transition: border-color .15s ease, box-shadow .15s ease, transform .1s ease;
    position: relative;
}
.pro-tennis-oop__match.is-clickable { cursor: pointer; }
a.pro-tennis-oop .pro-tennis-oop__match:hover,
.pro-tennis-oop a.pro-tennis-oop__match:hover {
    border-color: var(--pro-tennis-accent) !important;
    box-shadow: 0 2px 10px rgba(176, 29, 31, 0.12), 0 1px 4px rgba(15, 23, 42, 0.06) !important;
}
a.pro-tennis-oop__match:active { transform: translateY(1px); }

/* Top corners: time tag (left) + round code badge (right) */
.pro-tennis-oop__match-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--pro-tennis-text-muted);
}
.pro-tennis-oop__time {
    font-variant-numeric: tabular-nums;
}
.pro-tennis-oop__time--scheduled {
    color: var(--pro-tennis-text);
    font-weight: 700;
}
.pro-tennis-oop__code {
    background: var(--pro-tennis-bg-tab);
    padding: 2px 7px;
    border-radius: 4px;
    color: var(--pro-tennis-text-loser);
    font-size: 10.5px;
}

/* Center stack: players + thin separator */
.pro-tennis-oop__players {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 10px 4px;
    gap: 4px;
}
.pro-tennis-oop__player {
    font-size: 14px;
    line-height: 1.35;
    width: 100%;
    color: var(--pro-tennis-text-loser);
    overflow-wrap: anywhere;
}
.pro-tennis-oop__player.is-winner {
    color: var(--pro-tennis-text);
    font-weight: 700;
    position: relative;
}
/* Chip vincitore: sfondo verde chiaro arrotondato che avvolge il nome
 * (incluso flag e seed) e si adatta al testo. Multi-linea grazie a
 * box-decoration-break: clone — ogni line wrap riprende la chip.
 *
 * Tuning v3.10.30: verde piu' chiaro (#ecfdf5 = green-50) + line-height
 * 1.55 con padding 4px così le due linee della chip si toccano (overlap
 * di ~0.3px) e visivamente la chip multi-linea sembra continua, senza
 * stacco visibile. line-height = 1 + (2 * padding_v / font_size) = 1.57
 * e' il punto in cui le clone chip si toccano esattamente; 1.55 le fa
 * sovrapporre leggermente per fondersi visivamente. */
.pro-tennis-oop__player.is-winner .pro-tennis-oop__name {
    display: inline;
    background: #ecfdf5; /* green-50, pastello molto chiaro */
    padding: 4px 14px;
    border-radius: 999px;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    line-height: 1.55;
}
.pro-tennis-oop__player .pro-tennis-oop__name {
    display: block;
}
.pro-tennis-oop__player .pro-tennis-oop__alt {
    display: block;
    color: var(--pro-tennis-text-muted);
    font-size: 11.5px;
    font-style: italic;
    font-weight: 400;
}
/* Card con alternativa "or X" (vincitore di un match precedente non ancora
 * determinato): allineiamo il formato dei due nomi. In quel momento non
 * sappiamo chi giochera fra principale e alternativa — mostrarne uno
 * grande e l'altro piccolo/corsivo era fuorviante. Uniforminamo entrambi
 * al formato compatto del .__alt (italic, muted, 11.5px).
 *
 * :has() e supportato da tutti i browser moderni (Chrome/Edge 105+, Safari
 * 15.4+, Firefox 121+, tutti dal 2022 in poi). Su browser piu' vecchi la
 * regola viene ignorata e il rendering torna al comportamento attuale —
 * fallback accettabile. */
.pro-tennis-oop__player:has(.pro-tennis-oop__alt) .pro-tennis-oop__name {
    font-size: 11.5px;
    font-style: italic;
    font-weight: 400;
    color: var(--pro-tennis-text-muted);
}
.pro-tennis-oop__separator {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    margin: 4px 0;
    color: var(--pro-tennis-text-muted);
    font-size: 11px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}
.pro-tennis-oop__separator::before,
.pro-tennis-oop__separator::after {
    content: '';
    flex: 1;
    max-width: 60px;
    height: 1px;
    background: var(--pro-tennis-border);
}

/* Final score line for completed matches (after the players block).
 * Small bold tabular numbers with the tiebreak as superscript. */
.pro-tennis-oop__score-line {
    margin-top: 6px;
    text-align: center;
    font-size: 12px;
    color: var(--pro-tennis-text);
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.pro-tennis-oop__score {
    font-weight: 700;
    letter-spacing: 0.02em;
    /* Doppio spazio "visivo" tra un set e l'altro: word-spacing allarga
     * solo i caratteri spazio (non quelli all'interno di "6-2"), cosi
     * "6-1 6-2 10-6" diventa "6-1  6-2  10-6" senza toccare il markup.
     * 0.5em = circa la larghezza di uno spazio in piu' tra set. */
    word-spacing: 0.5em;
}
/* Da v3.10.144: variante "live" per i punteggi parziali (match in corso).
 * Da v3.10.145: stesso stile del loser nei tabelloni (color text-muted
 * #9ca3af + font-weight 500), così il parziale "sussurra" — l'utente
 * capisce a vista che e' diverso dai risultati definitivi (700 nero).
 * Niente bold pieno: il chip LIVE sopra la card fa gia' il segnale
 * primario, qui basta una differenza di peso/contrasto.
 */
.pro-tennis-oop__score--live {
    color: var(--pro-tennis-text-muted, #9ca3af);
    font-weight: 500;
}
.pro-tennis-oop__score sup {
    font-size: 0.7em;
    margin-left: 1px;
    vertical-align: super;
    font-weight: 600;
}
.pro-tennis-oop__score-flag {
    font-weight: 500;
    color: var(--pro-tennis-text-muted);
    margin-left: 4px;
    font-size: 0.9em;
}

.pro-tennis-oop__flag {
    display: inline-block;
    margin-right: 4px;
    font-size: 1em;
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
    vertical-align: -1px;
}
.pro-tennis-oop__flag--text {
    font-size: 9px;
    font-weight: 700;
    color: var(--pro-tennis-text-muted);
    border: 1px solid var(--pro-tennis-border);
    padding: 1px 4px;
    border-radius: 3px;
    margin-right: 4px;
    font-family: inherit;
    vertical-align: 1px;
}
.pro-tennis-oop__seed {
    color: var(--pro-tennis-text-muted);
    font-weight: 500;
    font-size: 0.7em;
    margin-left: 3px;
    vertical-align: super;
    line-height: 1;
}

/* Bottom corners: state badge (left) + click-through CTA (right) */
.pro-tennis-oop__match-bot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    min-height: 18px;
}
.pro-tennis-oop__state { display: inline-flex; align-items: center; }
.pro-tennis-oop__cta {
    color: var(--pro-tennis-text-muted);
    font-size: 14px;
    line-height: 1;
    transition: color .15s ease, transform .15s ease;
}
a.pro-tennis-oop__match:hover .pro-tennis-oop__cta {
    color: var(--pro-tennis-accent);
    transform: translate(2px, -2px);
}

.pro-tennis-oop__badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 2px 8px;
    border-radius: 99px;
}
.pro-tennis-oop__badge--live {
    background: var(--pro-tennis-live-bg);
    color: #365314;
}
.pro-tennis-oop__badge--live .pro-tennis-oop__live-dot {
    width: 6px; height: 6px; margin: 0;
    background: var(--pro-tennis-live);
    border-radius: 50%;
    box-shadow: 0 0 0 0 rgba(101, 163, 13, 0.7);
    animation: pro-tennis-oop-pulse 1.6s infinite;
}
.pro-tennis-oop__badge--done {
    background: var(--pro-tennis-bg-tab);
    color: var(--pro-tennis-text-loser);
}

/* Card states */
.pro-tennis-oop__match.is-state-live {
    border-color: var(--pro-tennis-live);
    box-shadow: 0 0 0 1px var(--pro-tennis-live) inset, 0 1px 2px rgba(0,0,0,0.04);
}
.pro-tennis-oop__match.is-state-completed {
    background: var(--pro-tennis-bg-done);
    border-color: var(--pro-tennis-border);
}
.pro-tennis-oop__match.is-state-completed .pro-tennis-oop__player {
    color: var(--pro-tennis-text-loser);
}
.pro-tennis-oop__match.is-state-completed .pro-tennis-oop__time,
.pro-tennis-oop__match.is-state-completed .pro-tennis-oop__code {
    opacity: 0.7;
}

/* Filter hidden state.
 * Da v3.10.59: tutti i filtri (boys/girls/singles/doubles/live) usano la
 * stessa UX uniforme — click attiva, click sull'attivo disattiva (mutex),
 * card non-matching nascoste del tutto e griglia ricomposta in row of
 * courts. Prima solo il filtro Live faceva cosi, gli altri sbiadivano
 * (effetto dim) — confondeva. Vedi roadmap #67.
 *
 * .is-filtered-out (sulla card) = "questa card non corrisponde al filtro
 *   attivo". Il fallback opacity 0.15 vale solo se il container NON ha
 *   .is-filter-active (es. JS non ancora caricato — graceful degrade).
 * .is-filter-active (sul container OOP) = "un qualsiasi filtro non-all
 *   e' attivo" — nasconde le card filtrate e ricompone la griglia.
 * .is-filter-live-active = alias per il caso live, mantenuto per
 *   eventuali stilizzazioni live-specific future (al momento nessuna). */
.pro-tennis-oop__match.is-filtered-out {
    opacity: 0.15;
    pointer-events: none;
}
.pro-tennis-oop.is-filter-active .pro-tennis-oop__match.is-filtered-out {
    display: none !important;
}
/* Filtro attivo: ricomponi visivamente in una riga di court colonne, con
 * il nome del campo in cima e le card filtrate sotto. Override del grid
 * colonne+slot+display:contents in flex row + flex column dentro ogni
 * court — cosi i nomi campi restano visibili, gli empty placeholder
 * spariscono, e le N court column si distribuiscono nello spazio.
 * Su mobile, una colonna per riga.
 *
 * align-items: flex-start sul grid: ogni colonna prende solo l'altezza
 * delle sue card (no stretch). Cosi se Court 3 ha 1 match e Court 4 ne
 * ha 3, la colonna 3 e' alta una card e la 4 ne e' alta tre — niente
 * card "allungata" per riempire spazio (richiesta utente 2026-05-10). */
.pro-tennis-oop.is-filter-active .pro-tennis-oop__grid {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    grid-template-columns: none !important;
    grid-template-rows: none !important;
    grid-auto-flow: row !important;
    align-items: flex-start !important;
    gap: 12px;
}
.pro-tennis-oop.is-filter-active .pro-tennis-oop__court {
    display: flex !important; /* override display:contents */
    flex-direction: column !important;
    flex: 1 1 220px !important;
    min-width: 220px !important; /* v3.10.125: min-width per scroll quando > 4 court matching */
    gap: 8px;
}
/* Da v3.10.125: quando il filtro e' attivo, nasconde i court che NON
 * hanno match matching (= tutti i loro match hanno la classe
 * is-filtered-out). Cosi la riga compatta mostra solo i campi
 * effettivamente coinvolti dal filtro, e lo spazio si redistribuisce.
 *
 * :has() supportato Chrome 105+ / Safari 15.4+ / Firefox 121+ — tutti
 * i browser moderni. Su browser molto vecchi i court vuoti rimangono
 * visibili (degrade ok). */
.pro-tennis-oop.is-filter-active .pro-tennis-oop__court:not(:has(.pro-tennis-oop__match:not(.is-filtered-out))) {
    display: none !important;
}
/* Match card in filter-active mode: niente piu' height: 100% / flex grow.
 * La card prende la sua altezza naturale e si impila in cima alla
 * colonna. Le colonne possono avere altezze diverse — corretto, perche'
 * dipende da quante card matching ha ognuna. */
.pro-tennis-oop.is-filter-active .pro-tennis-oop__match {
    height: auto !important;
    flex: 0 0 auto !important;
}
.pro-tennis-oop.is-filter-active .pro-tennis-oop__court-name {
    display: block !important;
    /* nome campo in cima alla colonna, anche se la colonna non ha card matching */
}
.pro-tennis-oop.is-filter-active .pro-tennis-oop__empty {
    display: none !important;
}
@media (max-width: 720px) {
    .pro-tennis-oop.is-filter-active .pro-tennis-oop__grid {
        flex-wrap: wrap !important;
    }
    .pro-tennis-oop.is-filter-active .pro-tennis-oop__court {
        flex: 1 1 100% !important;
        min-width: 100% !important;
    }
}

/* Mobile: stack courts vertically; full-width cards. Restore the per-court
 * flex column (cancel display:contents) so each court collapses to one stack.
 * !important obbligatori perché il PHP renderer setta grid-template-columns
 * inline per supportare un numero di campi variabile, e l'inline batte la
 * regola del media query senza !important. */
@media (max-width: 720px) {
    .pro-tennis-oop__grid,
    .pro-tennis-oop__grid[data-courts] {
        grid-auto-flow: row !important;
        grid-template-columns: 1fr !important;
        grid-template-rows: none !important;
        gap: 18px;
    }
    .pro-tennis-oop__court {
        display: flex !important;
        flex-direction: column;
        gap: 8px;
        background: #fafafa;
        border: 1px solid var(--pro-tennis-border);
        border-radius: 12px;
        padding: 12px;
    }
    .pro-tennis-oop__court-name {
        text-align: left;
        background: transparent;
        padding: 0 0 6px 0;
        border-bottom: 1px solid var(--pro-tennis-border);
        font-size: 14px;
        color: var(--pro-tennis-accent);
    }
    .pro-tennis-oop__match { width: 100%; }
    .pro-tennis-oop__empty { display: none; }
    .pro-tennis-oop__current-date { font-size: 16px; }
}

/* ============================================================
 * Tournament router shell — [pro-tennis-torneo]
 * Two-column layout: vertical sidebar on the left + content on
 * the right. Mobile collapses the sidebar behind a hamburger
 * overlay. The active menu item gets the brand red as background
 * with white text (per accessibility note in feedback memory).
 * ============================================================ */
/* Da v3.11.1: nascondi il badge reCAPTCHA di Google sulle pagine del
 * torneo (dove non c'e' nessun form da proteggere). Il badge altrimenti
 * copre il widget Error Console in basso a destra e ruba spazio visivo
 * inutilmente. La classe `pt-has-torneo` viene aggiunta al <body> dal
 * router quando la pagina contiene lo shortcode [pro-tennis-torneo]. */
body.pt-has-torneo .grecaptcha-badge {
    visibility: hidden !important;
    opacity: 0 !important;
    pointer-events: none !important;
}

.pt-torneo {
    font-family: 'Geist', system-ui, sans-serif;
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: 28px;
    max-width: 1200px;
    margin: 0 auto;
    align-items: start;
    /* NIENTE overflow-x qui per non rompere il position:sticky della
     * sidebar (vedi v3.10.162 + regressione v3.10.163). La protezione
     * dall'horizontal overflow e' applicata SOLO su mobile via media
     * query qui sotto. */
    box-sizing: border-box;
}
.pt-torneo__topbar { display: none; }

/* Sidebar — sticky on every view except home. On the home view the
 * sidebar holds info-boxes underneath the menu (which can be quite tall),
 * so we let it scroll naturally with the page; sticky there would clip
 * the info-boxes. On every other view the sidebar is just the menu —
 * sticky keeps it always reachable while scrolling brackets / OOP.
 * Note: overflow MUST stay visible so the disabled-item tooltips
 * (live score / streaming) can escape sideways without being clipped. */
.pt-torneo__sidebar {
    position: sticky;
    top: 110px;
    overflow: visible;
    /* `position: sticky` crea uno stacking context proprio: senza un z-index
     * esplicito, lo stacking context di .pt-torneo__main vince per DOM order
     * e copre i tooltip che escono a destra dalla sidebar. Bumpiamo qui per
     * far stare l'intera sidebar (e i suoi pop-out) sopra alla griglia. */
    z-index: 50;
}
@media (min-width: 821px) {
    .pt-torneo[data-view="home"] .pt-torneo__sidebar {
        /* Su home (desktop) niente sticky: la sidebar segue il flusso normale.
         * Manteniamo stacking context elevato (sezione "Adesso in campo" con
         * match-card a destra). Su mobile NON applichiamo questa regola così
         * la sidebar mantiene il comportamento overlay (position:fixed +
         * display:none default + display:block on .is-open) coerente con
         * tutte le altre viste — vedi la regola @media max-width:820px sotto. */
        position: relative;
        top: auto;
        overflow: visible;
        z-index: 50;
    }
}
.pt-torneo__menu { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.pt-torneo__menu-item a {
    display: flex; align-items: center; gap: 10px;
    padding: 11px 14px;
    background: var(--tcsc-accent, #b01d1f);
    color: #fff !important;
    text-decoration: none !important;
    border: 0; border-radius: 6px;
    font-size: 14px; font-weight: 600;
    letter-spacing: 0.005em;
    transition: background-color .15s ease, transform .1s ease;
    /* Anchor + clipping per la chip "COMPLETATO" assoluta in v3.10.96:
     * la chip galleggia in alto a destra e il label puo' scorrere sotto
     * senza far andare a capo la voce di menu. overflow:hidden taglia
     * la chip se mai sporge oltre il pulsante (non dovrebbe). */
    position: relative;
    overflow: hidden;
}
.pt-torneo__menu-item a:hover {
    background: #8a1518; /* darker red on hover */
    transform: translateX(2px);
    color: #fff !important;
}
.pt-torneo__menu-emoji { flex: 0 0 auto; font-size: 16px; line-height: 1; }
.pt-torneo__menu-label { flex: 1; }
/* Da v3.10.88: chip "COMPLETATO" su voci di menu di sezioni che hanno
 * concluso tutti i match dell'ultimo round (quali / main). Background
 * bianco + testo verde scuro per leggibilita' sul rosso accent.
 *
 * Da v3.10.96: assolutamente posizionata in alto a destra, leggermente
 * ruotata. NON occupa piu' spazio nel flusso flex del menu — la voce
 * "Tabelloni qualificazione" non va piu' a capo per fare spazio.
 * pointer-events: none cosi' il click sull'anchor passa attraverso. */
.pt-torneo__menu-status {
    position: absolute;
    top: 5px;
    right: 6px;
    font-size: 8px;
    font-weight: 800;
    letter-spacing: 0.05em;
    padding: 1px 5px;
    border-radius: 99px;
    text-transform: uppercase;
    background: #fefce8; /* yellow-50 — coerente con la chip Qualificato/a del bracket */
    color: #3f6212;
    line-height: 1.4;
    white-space: nowrap;
    transform: rotate(-8deg);
    transform-origin: center;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
    pointer-events: none;
    z-index: 2;
}
.pt-torneo__menu-status--done {
    /* future-proof modifier — placeholder per altri stati (es. "in corso") */
}
.pt-torneo__menu-item.is-active a {
    /* Active = darker red + white (still readable, key contrast rule) */
    background: #6f0f12;
    color: #fff !important;
    box-shadow: inset 3px 0 0 #fff;
    cursor: default;
}
.pt-torneo__menu-item.is-active a:hover {
    background: #6f0f12;
    transform: none;
}
/* Voce "Admin" — modificatore grigio scuro per lo shortcut wp-admin
 * visibile solo agli utenti con manage_options. Stessa forma/dimensione
 * delle altre voci, palette neutra per distinguerla dalla nav del torneo. */
.pt-torneo__menu-item.is-admin a {
    background: #374151; /* slate-700 */
}
.pt-torneo__menu-item.is-admin a:hover {
    background: #1f2937; /* slate-800 */
}
.pt-torneo__menu-item.is-external a::after {
    content: '↗';
    margin-left: auto;
    font-size: 12px;
    opacity: 0.85;
}

/* Main content area */
.pt-torneo__main {
    min-width: 0; /* prevent grid blowout from wide tables */
}
.pt-torneo__placeholder {
    background: #f9fafb;
    border: 1px dashed #d1d5db;
    border-radius: 8px;
    padding: 32px 24px;
    text-align: center;
    color: #4b5563;
}
.pt-torneo__placeholder p { margin: 6px 0; }

/* Storia view */
.pt-torneo__storia-body { font-size: 16px; line-height: 1.65; color: #1f2937; max-width: 760px; }
.pt-torneo__storia-body p { margin: 0 0 14px; }
.pt-torneo__storia-albo { margin-top: 36px; padding-top: 28px; border-top: 1px solid #e5e7eb; }

/* Sponsor grid */
.pt-sponsor__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 16px;
}
.pt-sponsor__cell {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    aspect-ratio: 4 / 3;
    display: flex; align-items: center; justify-content: center;
    padding: 18px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 2px 4px rgba(15, 23, 42, 0.03);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.pt-sponsor__cell img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    filter: grayscale(20%);
    transition: filter .2s ease;
}
/* Same soft red-tinted shadow as the OOP match cards. Applies to every cell
 * (even non-clickable ones) since the user found that hover lift pleasant. */
.pt-sponsor__cell:hover {
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 2px 10px rgba(176, 29, 31, 0.12), 0 1px 4px rgba(15, 23, 42, 0.06);
}
.pt-sponsor__cell:hover img { filter: grayscale(0%); }
/* Clickable variant adds a subtle lift; non-link cells stay in place. */
.pt-sponsor__cell--link { cursor: pointer; }
.pt-sponsor__cell--link:hover { transform: translateY(-1px); }
.pt-sponsor__cell--link:active { transform: translateY(1px); }

/* News grid */
.pt-news { font-family: 'Geist', system-ui, sans-serif; }
.pt-news__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 22px;
}
.pt-news__card {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    overflow: hidden;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.pt-news__card:hover {
    transform: translateY(-2px);
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08);
}
.pt-news__card-link { color: inherit !important; text-decoration: none !important; display: flex; flex-direction: column; height: 100%; }
.pt-news__card-link:hover { color: inherit !important; text-decoration: none !important; }
.pt-news__card-media {
    width: 100%; aspect-ratio: 16 / 9; background: #f3f4f6;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.pt-news__card-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pt-news__card-placeholder { font-size: 56px; opacity: 0.4; }
.pt-news__card-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.pt-news__card-cat {
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 700;
    color: var(--tcsc-accent, #b01d1f);
    margin-bottom: 2px;
}
.pt-news__card-title {
    font-size: 16px; font-weight: 700; line-height: 1.35; margin: 0; color: #111827;
    /* Da v3.10.146 (forzato in v3.10.147): niente sillabazione automatica.
     * Il tema WP applica hyphens:auto con specificita' alta su h1-h6 o su
     * h3.entry-title → senza !important il fix di v3.10.146 non scattava
     * (visto in produzione: titolo "MON-DIALE" continuava a spezzare).
     * Le parole vanno a capo intere; overflow-wrap break-word resta
     * come fallback solo se una parola e' piu' larga della card. */
    hyphens: none !important;
    -webkit-hyphens: none !important;
    -ms-hyphens: none !important;
    overflow-wrap: break-word;
}
.pt-news__card-excerpt { font-size: 13.5px; color: #4b5563; line-height: 1.55; margin: 0; }
.pt-news__card-foot {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: auto; padding-top: 8px;
    gap: 8px;
}
.pt-news__card-date { font-size: 11px; color: #9ca3af; }
.pt-news__card-cta {
    font-size: 14px;
    color: var(--tcsc-accent, #b01d1f);
    font-weight: 700;
    line-height: 1;
    transition: transform .15s ease;
}
.pt-news__card:hover .pt-news__card-cta { transform: translate(2px, -2px); }
.pt-news__pagination { margin-top: 32px; display: flex; justify-content: center; }
.pt-news__pagination ul { list-style: none; padding: 0; margin: 0; display: flex; gap: 6px; flex-wrap: wrap; }
.pt-news__pagination a, .pt-news__pagination span {
    display: inline-block; padding: 8px 14px;
    background: #fff; border: 1px solid #e5e7eb; border-radius: 4px;
    font-size: 13px; color: #4b5563; text-decoration: none !important;
}
.pt-news__pagination a:hover { background: #f3f4f6; }
.pt-news__pagination span.current { background: var(--tcsc-accent, #b01d1f); color: #fff !important; border-color: var(--tcsc-accent, #b01d1f); }

/* Mobile: hamburger overlay */
@media (max-width: 820px) {
    .pt-torneo {
        grid-template-columns: 1fr;
        gap: 16px;
        /* Da v3.10.163: overflow-x hidden SOLO su mobile (dove la
         * sidebar e' un drawer fixed, quindi non c'e' sticky da
         * rompere). Risolve la "striscia rossa" che compariva
         * scrollando su mobile. Su desktop l'overflow-x e' lasciato
         * default per preservare lo sticky della sidebar. */
        overflow-x: hidden;
    }
    .pt-torneo__topbar {
        display: flex; align-items: center; gap: 12px;
        background: var(--tcsc-accent, #b01d1f);
        color: #fff;
        padding: 12px 16px;
        border-radius: 6px;
        margin: 0 0 4px;
    }
    .pt-torneo__hamburger {
        background: rgba(255,255,255,0.12);
        color: #fff;
        border: 1px solid rgba(255,255,255,0.25);
        padding: 6px 12px;
        border-radius: 4px;
        font-weight: 600;
        cursor: pointer;
        font-size: 13px;
    }
    .pt-torneo__hamburger:hover { background: rgba(255,255,255,0.22); }
    .pt-torneo__current { font-weight: 600; font-size: 14px; }

    .pt-torneo__sidebar {
        position: fixed;
        inset: 0;
        background: rgba(15, 23, 42, 0.92);
        z-index: 9999;
        padding: 60px 24px 24px;
        display: none;
        overflow-y: auto;
    }
    .pt-torneo__sidebar.is-open { display: block; }
    .pt-torneo__sidebar::before {
        content: '✕';
        position: absolute;
        top: 16px; right: 22px;
        color: #fff;
        font-size: 22px;
        cursor: pointer;
    }
    .pt-torneo__menu-item a {
        font-size: 16px;
        padding: 14px 18px;
    }
    .pt-news__grid { grid-template-columns: 1fr; }
}

/* ============================================================
 * Tournament home — date strip, countdown, info+news row,
 * sponsor strip. Sits inside [pro-tennis-tournament-home] which
 * is rendered both standalone and via the router shell.
 * ============================================================ */
/* Date + countdown row: date a sinistra, countdown a destra (stessa riga) */
.pt-home__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 14px;
    margin: -36px 0 28px;
}
.pt-home__dates {
    font-size: 18px;
    font-weight: 700;
    color: var(--tcsc-text, #1a1a1a);
    letter-spacing: 0.01em;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.pt-home__countdown {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
    border: 1px solid #fbbf24;
    border-radius: 12px;
    padding: 10px 16px;
    box-shadow: 0 1px 3px rgba(180, 83, 9, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.pt-home__countdown-label {
    font-size: 12px;
    font-weight: 600;
    color: #92400e;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.pt-home__countdown-units {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-variant-numeric: tabular-nums;
}
.pt-home__countdown-unit {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    line-height: 1;
}
.pt-home__countdown-unit b {
    font-size: 18px;
    font-weight: 800;
    color: #92400e;
}
.pt-home__countdown-unit span {
    font-size: 9px;
    font-weight: 600;
    color: #b45309;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-top: 2px;
}
.pt-home__countdown-sep { color: #d97706; opacity: 0.5; }
@media (max-width: 540px) {
    .pt-home__countdown-unit b { font-size: 16px; }
}

/* Etichette di stato (subentrano al countdown):
 *  - is "live"      → torneo in corso (verde, dot pulsante)
 *  - is "concluded" → edizione conclusa (grigio neutro con trofeo)
 * Stessa "scatola" del countdown (padding, radius) per un'estetica coerente. */
.pt-home__status {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    border-radius: 12px;
    padding: 10px 16px;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.02em;
    box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.pt-home__status--live {
    background: linear-gradient(135deg, #dcfce7 0%, #bbf7d0 100%);
    border: 1px solid #86efac;
    color: #14532d;
}
.pt-home__status--live .pt-home__status-dot {
    width: 10px; height: 10px; border-radius: 50%;
    background: #16a34a;
    animation: pt-home-status-pulse 1.6s ease-out infinite;
}
@keyframes pt-home-status-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(22, 163, 74, .55); }
    70%  { box-shadow: 0 0 0 8px rgba(22, 163, 74, 0); }
    100% { box-shadow: 0 0 0 0 rgba(22, 163, 74, 0); }
}
.pt-home__status--concluded {
    background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
    border: 1px solid #d1d5db;
    color: #374151;
}
.pt-home__status--concluded .pt-home__status-icon { font-size: 16px; line-height: 1; }
.pt-home__status-label { line-height: 1.2; }

/* Da v3.10.159: CTA mobile-only "Vai al live score ufficiale" sotto il
 * titolo + meta (date/chip) e prima della sezione "MATCH IN CORSO".
 * Nascosto su desktop, full-width su mobile. Dot verde pulsante per
 * comunicare visivamente lo stato "live". Apre _blank l'URL FITP. */
.pt-home__mobile-live-cta {
    display: none; /* desktop default */
}
@media (max-width: 768px) {
    .pt-home__mobile-live-cta {
        display: flex;
        align-items: center;
        gap: 12px;
        width: 100%;
        padding: 14px 18px;
        margin: 14px 0 22px;
        background: var(--pro-tennis-accent, #b01d1f);
        color: #fff !important;
        border-radius: 14px;
        text-decoration: none !important;
        font-weight: 700;
        font-size: 15px;
        letter-spacing: 0.01em;
        line-height: 1.2;
        box-shadow: 0 4px 14px rgba(176, 29, 31, 0.25);
        transition: transform .2s ease, box-shadow .2s ease;
        -webkit-tap-highlight-color: transparent;
        box-sizing: border-box;
    }
    .pt-home__mobile-live-cta:hover,
    .pt-home__mobile-live-cta:focus,
    .pt-home__mobile-live-cta:active {
        color: #fff !important;
        transform: translateY(-1px);
        box-shadow: 0 6px 20px rgba(176, 29, 31, 0.35);
        text-decoration: none !important;
    }
    .pt-home__mobile-live-cta-dot {
        width: 9px;
        height: 9px;
        border-radius: 50%;
        background: #22c55e;
        box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.6);
        animation: ptHomeMobileLivePulse 1.6s ease-in-out infinite;
        flex-shrink: 0;
    }
    @keyframes ptHomeMobileLivePulse {
        0%, 100% { box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.65); transform: scale(1); }
        50%      { box-shadow: 0 0 0 8px rgba(34, 197, 94, 0);   transform: scale(0.92); }
    }
    .pt-home__mobile-live-cta-text {
        flex: 1;
        text-align: left;
    }
    .pt-home__mobile-live-cta-arrow {
        font-size: 20px;
        line-height: 1;
        flex-shrink: 0;
        transition: transform .2s ease;
    }
    .pt-home__mobile-live-cta:hover .pt-home__mobile-live-cta-arrow {
        transform: translateX(3px);
    }
}

.pt-home__section-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--tcsc-text, #1a1a1a);
    margin: 0 0 14px;
    padding-bottom: 0;
    border-bottom: 0;
}

.pt-home__news-section { margin: 36px 0 0; }

/* Info-box card (in left column) */
.pt-infoboxes { display: flex; flex-direction: column; gap: 14px; }
.pt-infobox {
    display: flex; flex-direction: column;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    overflow: hidden;
    text-decoration: none !important;
    color: inherit !important;
    transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 2px 4px rgba(15, 23, 42, 0.03);
}
.pt-infobox.is-clickable { cursor: pointer; }
.pt-infobox:hover {
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 2px 10px rgba(176, 29, 31, 0.12), 0 1px 4px rgba(15, 23, 42, 0.06);
}
.pt-infobox.is-clickable:hover { transform: translateY(-2px); }
.pt-infobox__img {
    width: 100%; aspect-ratio: 4 / 3; background: #f3f4f6;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.pt-infobox__img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pt-infobox__body { padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; }
.pt-infobox__title {
    margin: 0; font-size: 16px; font-weight: 700;
    display: flex; align-items: center; gap: 8px;
    color: #111827;
}
.pt-infobox__emoji { font-size: 20px; line-height: 1; }
.pt-infobox__desc { margin: 0; font-size: 13.5px; color: #4b5563; line-height: 1.5; }
.pt-infobox__btn {
    align-self: flex-start;
    background: var(--tcsc-accent, #b01d1f);
    color: #fff !important;
    text-decoration: none !important;
    padding: 8px 16px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 600;
    transition: background-color .15s ease;
    margin-top: 4px;
}
.pt-infobox__btn:hover { background: #8a1518; color: #fff !important; }

/* News preview in home — 3 columns by default (info-boxes moved to sidebar
 * so the news now have the full main column to themselves). */
.pt-home__news-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 16px;
}
@media (max-width: 820px) { .pt-home__news-grid { grid-template-columns: 1fr; } }
.pt-home__news-card {
    display: flex; flex-direction: column;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 10px;
    overflow: hidden;
    text-decoration: none !important;
    color: inherit !important;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 2px 4px rgba(15, 23, 42, 0.03);
    transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.pt-home__news-card:hover {
    transform: translateY(-2px);
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 6px 18px rgba(176, 29, 31, 0.10);
}
.pt-home__news-media {
    width: 100%; aspect-ratio: 16 / 10; background: #f3f4f6;
    display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.pt-home__news-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pt-home__news-placeholder { font-size: 36px; opacity: 0.4; }
.pt-home__news-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.pt-home__news-title { font-size: 14px; font-weight: 700; line-height: 1.35; margin: 0; color: #111827; }
.pt-home__news-date { font-size: 11px; color: #9ca3af; margin-top: auto; }
.pt-home__news-all, .pt-home__sponsor-all {
    display: inline-block;
    margin-top: 12px;
    font-size: 13px; font-weight: 600;
    color: var(--tcsc-accent, #b01d1f);
    text-decoration: none !important;
    border-bottom: 1px dashed currentColor;
    padding-bottom: 1px;
}
.pt-home__news-all:hover, .pt-home__sponsor-all:hover { opacity: 0.85; }

/* Sponsor strip in home (4 random) */
.pt-home__sponsor-strip { margin: 36px 0 0; padding-top: 24px; border-top: 1px dashed #e5e7eb; text-align: center; }
.pt-home__sponsor-strip-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 14px;
    margin-bottom: 12px;
}
.pt-home__sponsor-cell {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    aspect-ratio: 16 / 9;
    display: flex; align-items: center; justify-content: center;
    padding: 12px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    transition: border-color .15s ease, box-shadow .15s ease;
    text-decoration: none !important;
}
.pt-home__sponsor-cell:hover {
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 2px 10px rgba(176, 29, 31, 0.12);
}
.pt-home__sponsor-cell img {
    max-width: 100%; max-height: 100%;
    object-fit: contain;
    filter: grayscale(20%);
    transition: filter .2s ease;
}
.pt-home__sponsor-cell:hover img { filter: grayscale(0%); }

/* ============================================================
 * Router sidebar additions — social icons + live score states
 * ============================================================ */
.pt-socials {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 18px;
    padding-top: 0;
    border-top: 0;
    justify-content: center;
}
.pt-socials__icon {
    display: inline-flex;
    align-items: center; justify-content: center;
    width: 36px; height: 36px;
    border-radius: 50%;
    background: #f3f4f6;
    color: #4b5563;
    transition: background-color .15s ease, color .15s ease, transform .1s ease;
    text-decoration: none !important;
}
.pt-socials__icon svg { width: 18px; height: 18px; }
.pt-socials__icon:hover { transform: scale(1.08); color: #fff; }
.pt-socials__icon--instagram:hover { background: #E1306C; }
.pt-socials__icon--facebook:hover  { background: #1877F2; }
.pt-socials__icon--x:hover         { background: #0f0f0f; }
.pt-socials__icon--youtube:hover   { background: #FF0000; }
.pt-socials__icon--tiktok:hover    { background: #000000; }
.pt-socials__icon--linkedin:hover  { background: #0A66C2; }
.pt-socials__icon--threads:hover   { background: #000000; }
.pt-socials__icon--telegram:hover  { background: #229ED9; }
.pt-socials__icon--whatsapp:hover  { background: #25D366; }

/* Live score disabled state — keeps the exact same red box as the other
 * menu items but lighter/desaturated so it visibly reads as "not yet
 * active". The <a> stays an <a> (so all base styles apply) but click is
 * blocked via pointer-events while the surrounding <li> remains hoverable
 * to trigger the custom tooltip. */
.pt-torneo__menu-item.is-live-off > a {
    background: #d97a7c !important; /* lightened brand red */
    color: #fff !important;
    cursor: not-allowed;
    opacity: 0.85;
    pointer-events: none; /* clicks blocked, hover still bubbles to the <li> */
    box-shadow: none !important;
}
.pt-torneo__menu-item.is-live-off:hover > a {
    background: #d97a7c !important;
    transform: none !important;
}

/* Custom comic-bubble tooltip on the <li> wrapper. Centrato vertical-
 * mente sul menu item con freccia che punta a sinistra. Tighter margin
 * + width un filo piu' largo cosi il testo lungo (LIVESCORE 11 maggio…)
 * sta in 2 righe invece di 3, riducendo l'estensione verticale del
 * bubble (prima sembrava "spostato" perche' alto). */
.pt-torneo__menu-item { position: relative; }
.pt-torneo__menu-item.is-disabled[data-tooltip]::after {
    content: attr(data-tooltip);
    position: absolute;
    left: calc(100% + 12px);
    top: 50%;
    transform: translateY(-50%) scale(0.96);
    transform-origin: left center;
    background: #1f2937;
    color: #fff;
    padding: 8px 12px;
    border-radius: 8px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.4;
    white-space: normal;
    width: 240px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.10);
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
    z-index: 100;
}
.pt-torneo__menu-item.is-disabled[data-tooltip]::before {
    content: '';
    position: absolute;
    left: calc(100% + 4px);
    top: 50%;
    transform: translateY(-50%);
    border: 7px solid transparent;
    border-right-color: #1f2937;
    opacity: 0;
    transition: opacity .18s ease;
    z-index: 101;
    pointer-events: none;
}
.pt-torneo__menu-item.is-disabled[data-tooltip]:hover::after {
    opacity: 1;
    transform: translateY(-50%) scale(1);
}
.pt-torneo__menu-item.is-disabled[data-tooltip]:hover::before {
    opacity: 1;
}
@media (max-width: 820px) {
    .pt-torneo__menu-item.is-disabled[data-tooltip]::after,
    .pt-torneo__menu-item.is-disabled[data-tooltip]::before { display: none; }
}
/* Tooltip-on-top: il tooltip della voce disabilitata esce a destra dalla
 * sidebar e finiva COPERTO dai match-card sulla pagina OOP perché la
 * griglia main è successiva alla sidebar nel DOM e nessuno dei due aveva
 * z-index esplicito. Bumpiamo il z-index del tooltip oltre qualsiasi
 * elemento "ordinario" del torneo (le card hanno z-index auto = 0). */
.pt-torneo__menu-item.is-disabled[data-tooltip]:hover { z-index: 9999; }
.pt-torneo__menu-item.is-disabled[data-tooltip]::after  { z-index: 9999; }
.pt-torneo__menu-item.is-disabled[data-tooltip]::before { z-index: 10000; }

/* Info boxes inside the sidebar (under the socials, on home view only) */
.pt-torneo__sidebar-info {
    margin-top: 22px;
    padding-top: 0;
    border-top: 0; /* invisible divider as requested */
}
/* Credit della piattaforma sotto al menu (v3.10.76). Posizione visibile
 * subito sotto la nav, prima dei social. Stile leggibile ma non chiassoso:
 * font-size 12.5px, no italic, colore text-loser (piu' scuro del muted
 * usato per le icone social), underline solido sul link che si tinge di
 * accent rosso al hover. Separatore sottile in alto per stacco netto
 * dall'ultima voce di menu. */
.pt-torneo__credit {
    margin: 14px 0 0;
    padding: 12px 4px 0;
    font-size: 12.5px;
    color: var(--pro-tennis-text-loser);
    text-align: center;
    line-height: 1.45;
    border-top: 1px solid var(--pro-tennis-border);
}
.pt-torneo__credit a {
    color: var(--pro-tennis-text);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1px solid currentColor;
    transition: color .15s ease, border-bottom-color .15s ease;
}
.pt-torneo__credit a:hover {
    color: var(--pro-tennis-accent, #b01d1f);
    border-bottom-color: var(--pro-tennis-accent, #b01d1f);
}
/* Mobile (<=820px): la sidebar diventa overlay scuro (rgba 15,23,42,.92).
 * Il credit con i suoi colori desktop (grigio scuro su grigio) sparirebbe
 * sotto. Override a bianco solo nel breakpoint mobile (richiesta utente
 * 2026-05-10). v3.10.92: aggiunto !important sul link perche' qualcosa
 * lo sovrascriveva (probabilmente specificity o cache aggressiva). */
@media (max-width: 820px) {
    .pt-torneo__credit {
        color: rgba(255, 255, 255, 0.78) !important;
        border-top-color: rgba(255, 255, 255, 0.18) !important;
    }
    .pt-torneo__credit a {
        color: #fff !important;
        border-bottom-color: rgba(255, 255, 255, 0.7) !important;
    }
    .pt-torneo__credit a:hover {
        color: #fff !important;
        opacity: 0.85;
        border-bottom-color: #fff !important;
    }
}
.pt-torneo__sidebar-info-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #6b7280;
    margin: 0 0 10px;
    padding: 0;
}
.pt-torneo__sidebar-info .pt-infoboxes { gap: 10px; }
.pt-torneo__sidebar-info .pt-infobox { font-size: 13px; }
.pt-torneo__sidebar-info .pt-infobox__title { font-size: var(--pt-infobox-title-size, 14px); }
.pt-torneo__sidebar-info .pt-infobox__title--top { padding: 12px 12px 8px; margin: 0; }
.pt-torneo__sidebar-info .pt-infobox__body { padding: 12px 14px; gap: 6px; }
.pt-torneo__sidebar-info .pt-infobox__desc { font-size: var(--pt-infobox-desc-size, 12px); }
.pt-torneo__sidebar-info .pt-infobox__desc--rich { font-size: var(--pt-infobox-desc-size, 12px); }
.pt-torneo__sidebar-info .pt-infobox__desc--rich p { margin: 0 0 4px; font-size: var(--pt-infobox-desc-size, 12px); line-height: 1.5; }
.pt-torneo__sidebar-info .pt-infobox__desc--rich p:last-child { margin: 0; }
.pt-torneo__sidebar-info .pt-infobox__btn {
    /* Full-width per request — lo spazio sidebar è limitato e un CTA pieno
     * è più leggibile di uno piccolo allineato a sinistra. */
    display: block;
    width: auto;
    text-align: center;
    align-self: stretch;
    font-size: 13px;
    padding: 8px 12px;
    margin: 10px 12px 12px;
}
.pt-torneo__sidebar-info .pt-infobox.has-image .pt-infobox__btn { margin: 12px 14px 14px; }

/* Image-style infobox: title above, wide image, formatted text below */
.pt-infobox.has-image .pt-infobox__title--top {
    padding: 14px 16px 10px;
    margin: 0;
    color: #84cc16; /* brand-adjacent green per request */
    font-size: 18px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}
.pt-infobox.has-image .pt-infobox__img { aspect-ratio: auto; }
.pt-infobox.has-image .pt-infobox__img img { height: auto; max-height: none; }
.pt-infobox.has-image .pt-infobox__desc {
    padding: 14px 16px 0;
}
.pt-infobox.has-image .pt-infobox__desc--rich em { font-style: italic; color: #6b7280; }
.pt-infobox.has-image .pt-infobox__btn { margin: 12px 16px 16px; }
.pt-torneo__sidebar-info .pt-infobox.has-image .pt-infobox__title--top { font-size: 13px; padding: 10px 12px 6px; }
.pt-torneo__sidebar-info .pt-infobox.has-image .pt-infobox__desc { padding: 10px 12px 0; font-size: 12px; }

/* Hamburger sticky on mobile (so it stays reachable when scrolling). */
@media (max-width: 820px) {
    .pt-torneo__topbar {
        position: sticky;
        top: 0;
        z-index: 50;
    }
    .pt-home__sponsor-strip-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (max-width: 540px) {
    .pt-home__sponsor-strip-grid { grid-template-columns: 1fr; }
}

/* Mobile: bracket tabs + OOP filters scroll horizontally instead of wrapping. */
@media (max-width: 720px) {
    .pro-tennis-tabs__nav {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 4px;
    }
    .pro-tennis-tabs__nav::-webkit-scrollbar { display: none; }
    .pro-tennis-tabs__tab { flex: 0 0 auto; white-space: nowrap; }

    .pro-tennis-oop__filters {
        flex-wrap: nowrap !important;
        justify-content: flex-start !important; /* "Tutti" pinnato a sinistra,
                                                  no più tagliato dal centering */
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding-bottom: 4px;
        padding-left: 2px; /* respiro per non far attaccare al bordo */
        padding-right: 16px; /* hint visivo che si scrolla */
    }
    .pro-tennis-oop__filters::-webkit-scrollbar { display: none; }
    .pro-tennis-oop__filter,
    .pro-tennis-oop__filter-btn {
        flex: 0 0 auto;
        white-space: nowrap;
    }
}

/* ============================================================
 * Single news view — rendered inside the router shell when
 * ?pro_tennis_view=news&post=<id>. Read-friendly typography,
 * back link top + bottom for navigation.
 * ============================================================ */
.pt-news-single { font-family: 'Geist', system-ui, sans-serif; max-width: 760px; }
.pt-news-single__back {
    display: inline-block;
    font-size: 13px;
    font-weight: 600;
    color: var(--tcsc-accent, #b01d1f);
    text-decoration: none !important;
    margin-bottom: 16px;
}
.pt-news-single__back:hover { opacity: 0.85; }
.pt-news-single__back--bottom { margin: 36px 0 0; }
.pt-news-single__cats { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.pt-news-single__cat {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 700;
    color: var(--tcsc-accent, #b01d1f);
    background: rgba(176, 29, 31, 0.08);
    padding: 3px 9px;
    border-radius: 99px;
}
.pt-news-single__title {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.3;
    color: #111827;
    margin: 0 0 10px;
    letter-spacing: -0.01em;
    /* Da v3.10.146 (forzato in v3.10.147): vedi .pt-news__card-title. */
    hyphens: none !important;
    -webkit-hyphens: none !important;
    -ms-hyphens: none !important;
    overflow-wrap: break-word;
}
.pt-news-single__meta { color: #9ca3af; font-size: 13px; margin-bottom: 22px; }

/* Da v3.10.164: bottone "Copia link per Facebook" sulla news singola.
 * Apri/click → copia il permalink nella clipboard E richiama in
 * background l'endpoint REST del plugin che fa rescrape su Graph API
 * di Facebook. Risultato: anteprima FB completa al primo incolla. */
.pt-news-single__fb-share {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 24px;
    padding: 10px 18px;
    background: #1877f2;
    color: #fff;
    border: none;
    border-radius: 10px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background .18s ease, transform .18s ease, box-shadow .18s ease;
    box-shadow: 0 2px 6px rgba(24, 119, 242, 0.25);
    -webkit-tap-highlight-color: transparent;
}
.pt-news-single__fb-share:hover:not(:disabled) {
    background: #166fe5;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(24, 119, 242, 0.35);
}
.pt-news-single__fb-share:disabled {
    cursor: default;
    opacity: 0.85;
}
.pt-news-single__fb-share.is-loading {
    cursor: progress;
    opacity: 0.85;
}
.pt-news-single__fb-share.is-success {
    background: #16a34a;
    box-shadow: 0 4px 12px rgba(22, 163, 74, 0.35);
}
.pt-news-single__fb-share-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}
.pt-news-single__fb-share-text {
    white-space: nowrap;
}
.pt-news-single__media {
    width: 100%;
    margin: 0 0 24px;
    border-radius: 14px;
    overflow: hidden;
    background: #f3f4f6;
}
.pt-news-single__media img { display: block; width: 100%; height: auto; }
.pt-news-single__content {
    color: #1f2937;
    font-size: 16px;
    line-height: 1.7;
}
.pt-news-single__content p { margin: 0 0 16px; }
.pt-news-single__content h2 { font-size: 22px; margin: 28px 0 12px; color: #111827; }
.pt-news-single__content h3 { font-size: 18px; margin: 22px 0 10px; color: #111827; }
.pt-news-single__content a { color: var(--tcsc-accent, #b01d1f); }
.pt-news-single__content img { max-width: 100%; height: auto; border-radius: 10px; margin: 12px 0; }
.pt-news-single__content ul, .pt-news-single__content ol { padding-left: 22px; margin: 0 0 16px; }
.pt-news-single__content blockquote {
    margin: 16px 0;
    padding: 12px 18px;
    border-left: 3px solid var(--tcsc-accent, #b01d1f);
    background: #f9fafb;
    color: #4b5563;
    font-style: italic;
}

/* ============================================================
 * Page-builder gallery normalization. Containers are tagged at
 * render-time with the `pt-news-gallery` class (see PHP fixer in
 * router.php) so we can apply a strict grid layout regardless of
 * what builder emitted them (Themify / Elementor / Divi / WP core).
 * Highest priority: this comes before the generic .gallery rules. */
.pt-news-single .pt-news-single__content .pt-news-gallery {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    grid-auto-rows: 1fr !important;
    gap: 12px !important;
    margin: 18px 0 !important;
    padding: 0 !important;
    list-style: none !important;
    align-items: stretch !important;
    justify-items: stretch !important;
    /* Reset any flex/float the source markup may have set */
    flex: none !important;
    float: none !important;
}
/* Adapt column count to the actual number of children: 1 → 1 col, 2 → 2 col,
 * 3+ → 3 col (default). Uses :has() (Chromium 105+, Safari 15.4+, Firefox
 * 121+ — fine for modern browsers). */
.pt-news-single .pt-news-single__content .pt-news-gallery:has(> :only-child) {
    grid-template-columns: 1fr !important;
}
.pt-news-single .pt-news-single__content .pt-news-gallery:has(> :nth-child(2):last-child) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
/* Direct children of our wrapper are extracted <a> / <figure> / <img>
 * tags (the page-builder's outer divs are gone). Apply uniform aspect-
 * ratio cells with object-fit cropping. */
.pt-news-single .pt-news-single__content .pt-news-gallery > a,
.pt-news-single .pt-news-single__content .pt-news-gallery > figure,
.pt-news-single .pt-news-single__content .pt-news-gallery > img,
.pt-news-single .pt-news-single__content .pt-news-gallery > div {
    width: auto !important;
    max-width: none !important;
    min-width: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    flex: none !important;
    float: none !important;
    aspect-ratio: 4 / 3 !important;
    overflow: hidden !important;
    border-radius: 8px !important;
    background-color: #f3f4f6 !important;
    background-image: none !important;
    display: block !important;
    text-decoration: none !important;
    border: 0 !important;
    box-shadow: none !important;
}
.pt-news-single .pt-news-single__content .pt-news-gallery img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    object-position: center !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    display: block !important;
    aspect-ratio: auto !important;
    max-width: none !important;
    max-height: none !important;
}
/* Bare <a> needs to fill its grid cell so the click area covers the photo. */
.pt-news-single .pt-news-single__content .pt-news-gallery > a {
    display: flex !important;
    align-items: stretch !important;
    justify-content: stretch !important;
}
.pt-news-single .pt-news-single__content .pt-news-gallery > a > img,
.pt-news-single .pt-news-single__content .pt-news-gallery > figure > img {
    flex: 1 1 100% !important;
}
@media (max-width: 720px) {
    .pt-news-single .pt-news-single__content .pt-news-gallery {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
}
@media (max-width: 420px) {
    .pt-news-single .pt-news-single__content .pt-news-gallery {
        grid-template-columns: 1fr !important;
    }
}

/* ============================================================
 * Gallery override — AGGRESSIVE (legacy, kept as backup for
 * standard WP markup that doesn't trigger the PHP tagger above).
 * WordPress galleries come in 3 markup flavors:
 *   1. [gallery] shortcode → <div class="gallery"><dl class="gallery-item">
 *   2. Gutenberg block (legacy) → <ul class="wp-block-gallery blocks-gallery-grid">
 *   3. Gutenberg block (current) → <figure class="wp-block-gallery has-nested-images">
 * Each uses different float/flex layouts that break with mixed aspect
 * ratios (tall portrait next to short landscape). We force every variant
 * onto a strict CSS grid so the "row" never collapses.
 *
 * High specificity + !important is intentional: the host theme often has
 * its own .wp-block-gallery rules with high specificity that we must beat.
 * ============================================================ */
.pt-news-single .pt-news-single__content .gallery,
.pt-news-single .pt-news-single__content .wp-block-gallery,
.pt-news-single .pt-news-single__content figure.wp-block-gallery,
.pt-news-single .pt-news-single__content .blocks-gallery-grid,
.pt-news-single .pt-news-single__content ul.blocks-gallery-grid {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
    grid-auto-flow: row !important;
    grid-auto-rows: 1fr !important;
    gap: 12px !important;
    margin: 18px 0 !important;
    padding: 0 !important;
    list-style: none !important;
    flex-direction: unset !important;
    flex-wrap: unset !important;
    align-items: stretch !important;
    justify-items: stretch !important;
}
/* Honor user-chosen column counts when present. */
.pt-news-single .pt-news-single__content .gallery-columns-1,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-1 { grid-template-columns: 1fr !important; }
.pt-news-single .pt-news-single__content .gallery-columns-2,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-2 { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.pt-news-single .pt-news-single__content .gallery-columns-3,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-3 { grid-template-columns: repeat(3, minmax(0, 1fr)) !important; }
.pt-news-single .pt-news-single__content .gallery-columns-4,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-4 { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
.pt-news-single .pt-news-single__content .gallery-columns-5,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-5 { grid-template-columns: repeat(5, minmax(0, 1fr)) !important; }
.pt-news-single .pt-news-single__content .gallery-columns-6,
.pt-news-single .pt-news-single__content .wp-block-gallery.columns-6 { grid-template-columns: repeat(6, minmax(0, 1fr)) !important; }

/* Direct children of every gallery variant: kill float / max-width / flex. */
.pt-news-single .pt-news-single__content .gallery > *,
.pt-news-single .pt-news-single__content .wp-block-gallery > *,
.pt-news-single .pt-news-single__content .blocks-gallery-grid > *,
.pt-news-single .pt-news-single__content figure.wp-block-gallery > *,
.pt-news-single .pt-news-single__content .gallery .gallery-item,
.pt-news-single .pt-news-single__content .wp-block-gallery .blocks-gallery-item,
.pt-news-single .pt-news-single__content .wp-block-gallery .wp-block-image,
.pt-news-single .pt-news-single__content figure.wp-block-gallery figure {
    display: block !important;
    width: auto !important;
    max-width: none !important;
    min-width: 0 !important;
    margin: 0 !important;
    padding: 0 !important;
    flex: none !important;
    float: none !important;
    aspect-ratio: 4 / 3 !important;
    overflow: hidden !important;
    border-radius: 8px !important;
    background: #f3f4f6 !important;
}
/* Image inside any gallery item: always fill the cell, cropped for uniformity. */
.pt-news-single .pt-news-single__content .gallery img,
.pt-news-single .pt-news-single__content .wp-block-gallery img,
.pt-news-single .pt-news-single__content .blocks-gallery-grid img,
.pt-news-single .pt-news-single__content figure.wp-block-gallery img {
    width: 100% !important;
    height: 100% !important;
    object-fit: cover !important;
    object-position: center !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    border-radius: 0 !important;
    display: block !important;
    aspect-ratio: auto !important;
}
.pt-news-single .pt-news-single__content .gallery .gallery-caption,
.pt-news-single .pt-news-single__content .wp-block-gallery figcaption {
    display: none !important; /* drop captions inside the grid: they break the cell aspect ratio */
}
/* WordPress inserts <br style="clear:both"> between gallery rows; we don't need them. */
.pt-news-single .pt-news-single__content .gallery br,
.pt-news-single .pt-news-single__content .wp-block-gallery br { display: none !important; }

@media (max-width: 720px) {
    .pt-news-single .pt-news-single__content .gallery,
    .pt-news-single .pt-news-single__content .wp-block-gallery,
    .pt-news-single .pt-news-single__content .blocks-gallery-grid,
    .pt-news-single .pt-news-single__content .gallery-columns-3,
    .pt-news-single .pt-news-single__content .gallery-columns-4,
    .pt-news-single .pt-news-single__content .gallery-columns-5,
    .pt-news-single .pt-news-single__content .gallery-columns-6,
    .pt-news-single .pt-news-single__content .wp-block-gallery.columns-3,
    .pt-news-single .pt-news-single__content .wp-block-gallery.columns-4,
    .pt-news-single .pt-news-single__content .wp-block-gallery.columns-5,
    .pt-news-single .pt-news-single__content .wp-block-gallery.columns-6 {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
}
@media (max-width: 420px) {
    .pt-news-single .pt-news-single__content .gallery,
    .pt-news-single .pt-news-single__content .wp-block-gallery,
    .pt-news-single .pt-news-single__content .blocks-gallery-grid,
    .pt-news-single .pt-news-single__content [class*="gallery-columns-"],
    .pt-news-single .pt-news-single__content [class*="wp-block-gallery"][class*="columns-"] {
        grid-template-columns: 1fr !important;
    }
}
@media (max-width: 720px) {
    .pt-news-single__title { font-size: 19px; }
    .pt-news-single__content { font-size: 15px; }
}

/* ============================================================
 * Diretta streaming view — two layouts:
 *   .pt-streaming               link cards grid (1 card per court)
 *   .pt-streaming--embed        single inline iframe player
 * Lives inside [pro-tennis-torneo] when ?pro_tennis_view=streaming.
 * ============================================================ */
.pt-streaming { font-family: 'Geist', system-ui, sans-serif; }
.pt-streaming__title {
    font-size: 22px;
    font-weight: 700;
    margin: 0 0 6px;
    color: var(--tcsc-text, #111827);
}
.pt-streaming__intro { color: #6b7280; font-size: 14px; margin: 0 0 18px; }

/* Link cards grid */
.pt-streaming__links {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 14px;
}
.pt-streaming__link {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    padding: 18px 20px;
    color: inherit !important;
    text-decoration: none !important;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 2px 4px rgba(15, 23, 42, 0.03);
    transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.pt-streaming__link:hover {
    transform: translateY(-2px);
    border-color: var(--tcsc-accent, #b01d1f);
    box-shadow: 0 6px 18px rgba(176, 29, 31, 0.10);
}
.pt-streaming__link-icon { font-size: 32px; line-height: 1; }
.pt-streaming__link-label { font-size: 16px; font-weight: 700; color: #111827; }
.pt-streaming__link-cta {
    margin-top: auto;
    font-size: 13px;
    font-weight: 600;
    color: var(--tcsc-accent, #b01d1f);
}

/* Embed player — responsive 16:9 wrapper */
.pt-streaming--embed .pt-streaming__embed {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #0f172a;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
}
.pt-streaming--embed .pt-streaming__embed iframe,
.pt-streaming--embed .pt-streaming__embed video,
.pt-streaming--embed .pt-streaming__embed embed,
.pt-streaming--embed .pt-streaming__embed object {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    border: 0;
}

/* Multi-stream embed (v3.10.101): tabs + iframe panes (uno per campo).
 * Stesso look del player single-embed, con la nav dei tab sopra. */
.pt-streaming--multi .pt-streaming__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
}
.pt-streaming--multi .pt-streaming__tab {
    appearance: none;
    border: 1px solid #d1d5db;
    background: #fff;
    color: #1f2937;
    font: 600 14px/1 'Geist', system-ui, sans-serif;
    padding: 10px 16px;
    border-radius: 999px;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.pt-streaming--multi .pt-streaming__tab:hover {
    background: #f9fafb;
    border-color: #9ca3af;
}
.pt-streaming--multi .pt-streaming__tab.is-active {
    background: var(--tcsc-accent, #b01d1f);
    border-color: var(--tcsc-accent, #b01d1f);
    color: #fff;
}
.pt-streaming--multi .pt-streaming__panes {
    position: relative;
}
.pt-streaming--multi .pt-streaming__pane {
    display: none;
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #0f172a;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 4px 14px rgba(15, 23, 42, 0.08);
}
.pt-streaming--multi .pt-streaming__pane.is-active { display: block; }
.pt-streaming--multi .pt-streaming__pane iframe,
.pt-streaming--multi .pt-streaming__pane video,
.pt-streaming--multi .pt-streaming__pane embed,
.pt-streaming--multi .pt-streaming__pane object {
    position: absolute;
    inset: 0;
    width: 100% !important;
    height: 100% !important;
    border: 0;
}

/* Da v3.10.103: link "Apri su YouTube" sotto al player multi-tab. */
.pt-streaming--multi .pt-streaming__external {
    margin-top: 14px;
    padding: 12px 14px;
    background: #f9fafb;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
}
.pt-streaming--multi .pt-streaming__external-intro {
    margin: 0 0 8px;
    font-size: 13px;
    color: #6b7280;
}
.pt-streaming--multi .pt-streaming__external-links {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.pt-streaming--multi .pt-streaming__external-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 6px;
    background: #fff;
    border: 1px solid #d1d5db;
    color: #111827;
    text-decoration: none;
    font: 600 13px/1.2 'Geist', system-ui, sans-serif;
    transition: background-color .15s ease, border-color .15s ease;
}
.pt-streaming--multi .pt-streaming__external-link:hover {
    background: #f3f4f6;
    border-color: #9ca3af;
    color: #111827;
}

/* Streaming menu item — same disabled visual as Live score (lightened red). */
.pt-torneo__menu-item.is-streaming-off > a {
    background: #d97a7c !important;
    color: #fff !important;
    cursor: not-allowed;
    opacity: 0.85;
    pointer-events: none;
    box-shadow: none !important;
}
.pt-torneo__menu-item.is-streaming-off:hover > a {
    background: #d97a7c !important;
    transform: none !important;
}

/* ============================================================
 * Scheda giocatore (vista [pro-tennis-torneo] ?pro_tennis_view=player)
 * Header con bandiera + nome + tabellone + back link, lista cronologica
 * dei match con round, data, avversario, score, esito (vittoria/sconfitta).
 * ============================================================ */
.pt-player { font-family: 'Geist', system-ui, sans-serif; max-width: 880px; }
.pt-player__back {
    display: inline-block;
    font-size: 13px;
    font-weight: 600;
    color: var(--pro-tennis-text-muted);
    text-decoration: none;
    margin-bottom: 14px;
}
.pt-player__back:hover { color: var(--pro-tennis-accent); }
.pt-player__head {
    background: linear-gradient(135deg, #fff 0%, #fafafa 100%);
    border: 1px solid var(--pro-tennis-border);
    border-radius: 12px;
    padding: 22px 26px;
    margin-bottom: 18px;
}
.pt-player__name {
    font-size: 24px; font-weight: 700; line-height: 1.15;
    margin: 0 0 4px;
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    color: var(--pro-tennis-text);
}
.pt-player__flag { font-size: 1em; line-height: 1; }
.pt-player__seed {
    font-size: 13px; font-weight: 500;
    color: var(--pro-tennis-text-muted);
    vertical-align: super;
}
.pt-player__sub {
    font-size: 13px; color: var(--pro-tennis-text-muted);
    text-transform: uppercase; letter-spacing: 0.04em; font-weight: 600;
}
/* Pannello "Profilo ITF" sopra la lista match nella scheda giocatore.
 * Da v3.10.55: sempre aperto. Niente piu' <details>/<summary>, niente
 * bottone — il pannello viene mostrato direttamente sotto al nome con
 * foto + dati. Il titolo "Percorso del giocatore" sopra (h3 rosso del
 * tema) fa da intestazione gerarchica per tutta la zona profilo. */
.pt-player__itf {
    background: linear-gradient(135deg, #fff 0%, #fafafa 100%);
    border: 1px solid var(--pro-tennis-border);
    border-radius: 10px;
    margin: 0 0 18px;
    overflow: hidden;
}
.pt-player__itf-body {
    padding: 16px;
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 16px;
    align-items: start;
}
.pt-player__itf-photo {
    width: 120px;
    height: 150px;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--pro-tennis-border);
    background: #f3f4f6;
}
.pt-player__itf-stats {
    margin: 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px 18px;
    font-size: 13px;
}
.pt-player__itf-stats > div {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.pt-player__itf-stats dt {
    font-size: 11px;
    color: var(--pro-tennis-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}
.pt-player__itf-stats dd {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--pro-tennis-text);
}
.pt-player__itf-source {
    grid-column: 1 / -1;
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--pro-tennis-text-muted);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 6px;
}
.pt-player__itf-source a {
    color: var(--pro-tennis-accent);
    text-decoration: none;
    font-weight: 600;
}
.pt-player__itf-source a:hover { text-decoration: underline; }
.pt-player__itf-credit { font-style: italic; }
.pt-player__itf-loading {
    grid-column: 1 / -1;
    margin: 0;
    color: var(--pro-tennis-text-muted);
    font-size: 13px;
    font-style: italic;
}
/* Win-rate bar: barra verde (vinte) + rosso pastello (perse) larghezze
 * proporzionali al win/loss count. Sopra label compatta col percent. */
.pt-player__itf-winrate {
    grid-column: 1 / -1;
    margin: 4px 0 0;
}
.pt-player__itf-winrate-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    font-size: 11px;
    color: var(--pro-tennis-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
    margin-bottom: 4px;
}
.pt-player__itf-winrate-label strong { color: var(--pro-tennis-text); font-size: 13px; }
.pt-player__itf-winrate-counts { font-weight: 500; text-transform: none; letter-spacing: 0; font-size: 12px; }
.pt-player__itf-winrate-bar {
    display: flex;
    height: 8px;
    border-radius: 99px;
    overflow: hidden;
    background: var(--pro-tennis-border);
}
.pt-player__itf-winrate-wins   { background: #16a34a; }
.pt-player__itf-winrate-losses { background: #fca5a5; }
.pt-player__itf-body--minimal { grid-template-columns: 1fr; }
.pt-player__itf-empty {
    margin: 0;
    color: var(--pro-tennis-text);
    font-size: 13px;
    line-height: 1.45;
}
@media (max-width: 540px) {
    .pt-player__itf-body { grid-template-columns: 90px 1fr; gap: 12px; padding: 12px; }
    .pt-player__itf-photo { width: 90px; height: 112px; }
    .pt-player__itf-stats { grid-template-columns: 1fr; }
}

/* Titolo della singola sezione (Qualificazioni / Tabellone principale) —
 * compare solo quando il giocatore ha tratti multipli (qualificato passato
 * al main): le sezioni vanno separate visivamente. */
/* Page title (rosso tema) — segna le grandi sezioni della pagina giocatore:
 * "Percorso del giocatore" sopra al nome + profilo ITF, e "Percorso nel
 * torneo" sopra ai tabelloni con le partite. E' il livello h3 piu' alto
 * della pagina, sopra ai sub-titoli di tabellone. */
.pt-player__page-title {
    font-size: 18px;
    font-weight: 700;
    color: var(--pro-tennis-accent, #b01d1f);
    margin: 28px 0 14px;
    letter-spacing: 0.01em;
}
.pt-player__page-title:first-of-type { margin-top: 16px; }

/* Sub-titoli "TABELLONE DI QUALIFICAZIONE" / "TABELLONE PRINCIPALE":
 * grigio scuro tema (era rosso accent fino a v3.10.54). Il rosso e'
 * riservato ai page-title sopra — gerarchia visiva piu' chiara. */
.pt-player__section-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--pro-tennis-text);
    margin: 22px 0 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--pro-tennis-border);
}
.pt-player__section-title:first-of-type { margin-top: 4px; }
.pt-player__section-tn {
    color: var(--pro-tennis-text-muted);
    font-weight: 500;
    text-transform: none;
    letter-spacing: 0;
    font-size: 12px;
}
.pt-player__matches { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
/* Più aria tra il blocco main e quello quali (richiesta utente 2026-05-09):
 * 26px erano poco — la riga rossa di sezione si appoggiava al match precedente.
 * Bump a 44px per uno stacco netto.
 * v3.13.2: bump ulteriore a 72px su richiesta utente — 44px ancora poco
 * percepito. Inline style con !important applicato anche da router.php per
 * dare doppia protezione contro cache/theme override. */
.pt-player__matches + .pt-player__section-title { margin-top: 72px; }
/* Spazio extra quando un section-title (es. "TABELLONE DI QUALIFICAZIONE")
 * segue immediatamente un page-title (es. "Percorso nel torneo"): senza
 * questa regola i due titoli si appoggiavano e perdevano gerarchia visiva.
 * 56px = stacco molto netto, due righe di "respiro" tra il page-title
 * rosso e il sub-titolo del tabellone in grigio.
 *
 * Da v3.10.74: aggiunto !important. La regola da sola non garantiva lo
 * stacco visivo sul live (vedi roadmap #70 — sospettata cache CDN/theme
 * override). In aggiunta, lo stacco e' ora applicato via INLINE style
 * sul page-title in router.php (margin-bottom 56px !important) cosi
 * abbiamo doppia protezione. Margin collapse fa max(56, 56) = 56px. */
.pt-player__page-title + .pt-player__section-title { margin-top: 56px !important; }
.pt-player__match {
    background: #fff;
    border: 1px solid var(--pro-tennis-border);
    border-left: 3px solid var(--pro-tennis-border);
    border-radius: 8px;
    padding: 14px 16px;
    display: grid;
    grid-template-columns: 180px 1fr;
    gap: 14px;
    align-items: center;
}
.pt-player__match:has(.pt-player__outcome--win) { border-left-color: #16a34a; background: #f0fdf4; }
.pt-player__match:has(.pt-player__outcome--loss) { border-left-color: #b91c1c; }
/* Da v3.10.90: match "da giocare" ora ha lo stesso trattamento visivo
 * del match vinto, ma in tonalita' grigio chiaro (parallelo a #f0fdf4
 * verde). Niente piu' opacity 0.85 — il box e' solido come gli altri. */
.pt-player__match:has(.pt-player__outcome--pending) {
    border-left-color: #9ca3af;
    background: #f3f4f6;
}
.pt-player__match-meta { display: flex; flex-direction: column; gap: 3px; }
.pt-player__round { font-weight: 700; font-size: 14px; color: var(--pro-tennis-text); }
.pt-player__date { font-size: 12px; color: var(--pro-tennis-text-muted); text-transform: capitalize; }
.pt-player__match-body { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.pt-player__opponent { font-size: 14px; }
.pt-player__opponent-name { font-weight: 500; }
.pt-player__opponent--bye { color: var(--pro-tennis-text-muted); font-style: italic; }
.pt-player__vs { color: var(--pro-tennis-text-muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.05em; margin-right: 4px; }
.pt-player__match-result { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pt-player__score {
    font-family: Menlo, Consolas, monospace;
    font-size: 13px; font-weight: 600;
    color: var(--pro-tennis-text);
    background: rgba(0,0,0,0.04);
    padding: 3px 8px; border-radius: 4px;
    font-variant-numeric: tabular-nums;
}
.pt-player__outcome {
    font-size: 11px; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em;
    padding: 3px 9px; border-radius: 99px;
}
.pt-player__outcome--win {
    background: #16a34a; color: #fff;
}
.pt-player__outcome--loss {
    background: #fee2e2; color: #b91c1c;
}
.pt-player__outcome--pending {
    /* Pill un pelino piu' scura del box grigio del match (#f3f4f6) per
     * staccarsi visivamente — gray-300 vs gray-100. */
    background: #d1d5db;
    color: #374151;
}
.pt-player__empty {
    color: var(--pro-tennis-text-muted);
    font-style: italic;
    padding: 24px;
    text-align: center;
    background: #f9fafb;
    border: 1px dashed var(--pro-tennis-border);
    border-radius: 8px;
}
@media (max-width: 540px) {
    .pt-player__match { grid-template-columns: 1fr; gap: 8px; }
    .pt-player__match-body { gap: 10px; }
    .pt-player__name { font-size: 20px; }
}
