/* tokens.css */
/* ============================================================
   TOKENS: one palette for the whole site, word for word.
   No page invents a palette of its own: it is the same house.
   ============================================================ */
/* ============================================================
   THE DISPLAY TYPEFACE
   ============================================================
   Gunship, by Daniel Zadorozny (Iconian Fonts). Squared, all caps in
   the way we use it: titles and headings, NEVER running text. Five
   thousand words of the safeguarding document set this way would not
   be readable.

   IT IS OURS AND IT LIVES IN HERE: no typeface comes from outside,
   just as no script and no map does. 37 KB that travel as 14, and they
   download only if something really uses them.

   THE LICENCE IS FOR NON COMMERCIAL USE and the club is a non profit
   ASD (confirmed by the club, 18 August 2026). The licence text
   travels next to the file, in assets/font/, because that is what the
   licence itself asks.

   swap: text shows AT ONCE in the system typeface and changes when the
   file arrives. The alternative is half a second of invisible titles
   on a slow connection in a gym. */
@font-face{
  font-family:"Gunship";
  /* The CONDENSED cut and not the round one: round, in caps and
     letterspaced, pulls words wide until they look stretched. This
     says the same thing in less room. */
  src:url("/font/gunship-cond.147f7ded.ttf") format("truetype");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}

:root{
  /* The display typeface is named HERE and used by name: the day it
     changes, it changes in one place. The fallback is not "some sans
     or other" but the system stack the site already uses, so until the
     file arrives the page stays the same. */
  --titoli:"Gunship",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  /* THE HEADER HEIGHT AND THE CREST HEIGHT, in one place only.
     The drawer MUST be as tall as the strip it covers, or opening the
     menu makes the mark jump. One number instead of several kept in
     agreement by hand, each one an occasion to get it wrong.
     The crest sits seven pixels below the top edge and seven above the
     bottom one, and that air is what makes it read as a mark rather
     than a plug forced between two edges. Seven and not fourteen: at
     fourteen the strip becomes a tall header, and a tall header takes
     a band of page away from every screen of every page.
     ONE MEASURE FOR BOTH SCREENS, with no phone exception: an
     exception that distinguishes nothing is just one more place to
     remember to look.
     The width comes from the height: 1.356 is the proportion of the
     file as the pipeline produces it, white rule included. */
  --testa:70px;
  --stemma:56px;
  /* --pad IS THE PAGE MARGIN, --gap THE STEP BETWEEN PANELS, and they
     are the same number. Equal, the page reads as filled instead of
     framed, and the width goes back to the content, which is what the
     dense pages need: home, calendar, results.
     TWO TOKENS AND NOT ONE because they say two different things: the
     day the page margin has to be wider than the step, this one
     changes and the other does not. */
  --pad:13px;
  --gap:13px;
  --ground:#D3E4EF;
  --head:#FFFFFF;
  --head-fg:#0B1A22;
  --head-dim:#54697A;
  --head-line:#C2D8E5;
  --menu-line:#E2ECF2;
  --chrome-btn:rgba(4,26,40,.06);
  --chrome-btn-h:rgba(4,26,40,.13);
  --brand-dim:#02629B;
  /* THE CHROME AMBER: the menu item that stands apart (safeguarding).
     Not a highlight. A bright colour at the end of the row would read
     as the main button, the opposite of what this is. It is picked as
     LIGHT as the other items (--head-dim) and differs only in tint: it
     shows as belonging to another group, not as shouting. */
  --head-nota:#7A5F1E;
  /* The veil of that same item when its page is open. It is the amber
     itself, barely laid on the ground: "you are here" said with the
     colour that item already has, instead of borrowing the blue of all
     the others, which would fold it back into the group it stays out
     of the rest of the time.
     In rgba and not in hex because there are two grounds, the white
     header and the black one, and one veil follows both. */
  --head-nota-fill:rgba(122,95,30,.15);
  --chrome-sel:#DCEDF7;
  --chrome-sel-fg:#0377BD;
  --panel:#FFFFFF;
  --bar:#E8F2F8;
  --bar-fg:#0B1A22;
  --bar-dim:#54697A;
  --bar-line:#CFE0EB;
  --zebra:#EBF2F7;
  --sunken:#DCE7EF;
  --line:#B7CBD9;
  /* THE COUNTDOWN BOXES, one tone for both screens. The phone sheet
     redefines --line and --zebra to something much softer: right for
     its own furniture, wrong here, since these four boxes are the same
     object on both and would come out outlined in fog on the phone and
     drawn on the desk. Declared here and NOT overridden in
     tel/tokens.css, which is what makes them match. */
  --cd-fill:#EBF2F7;
  --cd-line:#B7CBD9;
  --tratteggio:#B7CBD9;
  --line-2:#95B0C3;
  --edge:#8FADC0;
  --ink:#020909;
  --ink-2:#2B3C45;
  --muted:#475965;
  --faint:#647987;
  --brand:#0377BD;
  --brand-2:#02547F;
  --accent:#52B2D0;
  --on-brand:#FFFFFF;
  /* Won / lost: the only two "semantic" colours of the house. They do
     not flip between the two themes. Green and red hold on both
     grounds, and changing them would look like two different clubs. */
  --up:#12885A;
  --down:#C6412F;
  /* THE LIGHT GREEN AND RED. They are --up and --down thinned into the
     ground, and they serve where the outcome is a PATCH and not a thin
     word: the block of a calendar cell and the win/loss label in the
     match card. The saturated full shouts there. In a grid of forty
     cells it turns into a green and red chessboard, and next to two
     lines of text it pulls the eye off the names. Full --up or --down
     goes on top and stays the semantic colour of the house: the tone
     changes, the meaning does not.
     WRITTEN IN HEX AND NOT IN rgba(): a transparent veil leans on
     whatever is under it, and here there are three different grounds
     (panel, weekday cell, weekend cell). With a solid colour the
     contrast is a single number and can be measured, and tests/theme.js
     does measure it, in both themes: 3,4:1 green and 3,7:1 red in the
     light, 3,4:1 and 3,3:1 in the dark.
     A DRAW has no token of its own: it is neutral, and the neutral is
     already there (--line-2). A third colour for "neither one nor the
     other" would say something happened, and nothing did. */
  --up-fill:#C9E7D8;
  --down-fill:#F6D6D0;
  /* THE AMBER: neither won nor lost, but "look here". It serves in one
     place only: the list of warning signs in the safeguarding
     document, which neither forbids nor obliges but asks to notice.
     Like green and red it does not flip between the two themes. It is
     a semantic colour, and changing it in the dark would mean two
     meanings for the same sign. */
  --warn:#A8730A;
  /* The veil that marks Silea: in the table, in the match list row, in
     the chosen item of the selector. Always this one, never a solid
     brand fill: in the dark, white text over light cyan sits at 2,3:1
     and does not read. */
  --me-fill:rgba(164,210,230,.46);
  /* The neutral twin of --me-fill: where --me-fill says "this is
     ours", this one says "this is not". It grounds the left half of a
     calendar cell, which for an away match cannot be brand. Not a new
     colour but --muted veiled, so it follows the theme without chasing
     it, and it stays transparent: a solid ground would disappear over
     the weekend cell, which already has a ground of its own. */
  --via-fill:rgba(71,89,101,.14);
  --scrim:rgba(2,9,9,.55);
  /* Height of the result panel body: FIXED, the same for a played
     match, a countdown and a bye. One number, and one only: without
     it the panel changes size at every change of matchday and the
     whole column flickers. */
  --hero-h:270px;
  --shadow:0 16px 40px -18px rgba(6,30,46,.28);
  --bird-op:.40;
  /* THE SPARROW HAS TWO VERSIONS, one for light grounds and one for
     dark, and the choice happens HERE because it appears in three
     different sheets (the three shapes of the result card) and
     choosing in three places means forgetting in one.
     On light goes the DARK version and the other way round: the file
     name says what colour the drawing is, not what ground it goes on.
     Two files and not a filter computed on screen: the sparrow is made
     of thin strokes, the open wing is all feathers, and any tint
     inversion smears them. These two were drawn by whoever made the
     mark. */
  --passero:url("/icona-dark.1a2459a0.png");
  /* THE 5x1000 SHAPES, watermarked inside the panel.
     The file is white on nothing (three solid shapes, not a line
     drawing) and white as a watermark works only on the dark: on the
     light board the panel lets the pale blue of the page through, and
     on the phone it has the paper ground, where white on white is
     nothing. So the file is used not as an image but as a MASK: it
     gives the shape, this line gives the colour, and one single file
     tints the watermark as needed on any ground.
     The alpha sits inside the colour instead of in a separate opacity:
     one thing to tune, not two.
     Lower than the sparrow (--bird-op, .40) because these are solid
     surfaces and not feathers: at the same opacity they would not be a
     watermark, they would be an illustration behind the text. */
  --sagome:rgba(3,119,189,.11);
  /* THE VEIL. A ground that lightens what sits under it instead of
     covering it: for where a panel rests over a watermark and must not
     erase it. White and not a solid tone, because it has to work over
     whatever ends up behind it. */
  --velo:rgba(255,255,255,.34);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ground:#010506; --panel:#04090C; --bar:#0E1D26; --bar-fg:#E6F1F7;
    --bar-dim:#8CA3B0; --zebra:#0A141A; --sunken:#0F1E27; --line:#182831;
    --line-2:#2A404E; --tratteggio:#425768; --cd-fill:#0A141A; --cd-line:#22343E; --edge:#395666; --ink:#F4FAFC; --ink-2:#BFCFD8;
    --muted:#90A5B1; --faint:#6E8490; --brand:#52B2D0; --brand-2:#8AD0E4;
    --on-brand:#03151C;
    /* --up and --down never flip, but the ground they are thinned into
       does: in the dark "light" means a very dark green and red, or a
       light theme patch inside a black page turns into a lightbulb.
       Declared in all three states, or at night they would sit at the
       light value by accident and not by choice. */
    --up-fill:#0E2A20;
    --down-fill:#33170F;
    --me-fill:rgba(82,178,208,.16);
    --via-fill:rgba(144,165,177,.14);
    /* in the dark the scrim and the shadow go strong: on a dark ground
       the soft ones of the light theme would not show */
    --scrim:rgba(0,0,0,.66);
    --shadow:0 24px 60px -18px rgba(0,0,0,.6);
    --head:#020909; --head-fg:#FFFFFF; --head-dim:#9FB1BC; --head-line:#122029;
    --menu-line:#16232A;
    --chrome-btn:rgba(255,255,255,.10); --chrome-btn-h:rgba(255,255,255,.22);
    --chrome-sel:rgba(255,255,255,.14); --chrome-sel-fg:#FFFFFF;
    --brand-dim:#75C1D9;
    /* In the dark the amber lightens like everything else: dim gold,
       at the same lightness as --head-dim. */
    --head-nota:#BFA671;
    --head-nota-fill:rgba(191,166,113,.17);
    --bar-line:#16262F;
    --bird-op:.10;
    --passero:url("/icona.e2a83984.png");
    --sagome:rgba(255,255,255,.06);
    --velo:rgba(255,255,255,.04);
  }
}
:root[data-theme="dark"]{
  --ground:#010506; --panel:#04090C; --bar:#0E1D26; --bar-fg:#E6F1F7;
  --bar-dim:#8CA3B0; --zebra:#0A141A; --sunken:#0F1E27; --line:#182831;
  --line-2:#2A404E; --tratteggio:#425768; --cd-fill:#0A141A; --cd-line:#22343E; --edge:#395666; --ink:#F4FAFC; --ink-2:#BFCFD8;
  --muted:#90A5B1; --faint:#6E8490; --brand:#52B2D0; --brand-2:#8AD0E4;
  --on-brand:#03151C;
  --up-fill:#0E2A20;
  --down-fill:#33170F;
  --me-fill:rgba(82,178,208,.16);
  --via-fill:rgba(144,165,177,.14);
  --scrim:rgba(0,0,0,.66);
  --shadow:0 24px 60px -18px rgba(0,0,0,.6);
  --head:#020909; --head-fg:#FFFFFF; --head-dim:#9FB1BC; --head-line:#122029;
  --menu-line:#16232A;
  --chrome-btn:rgba(255,255,255,.10); --chrome-btn-h:rgba(255,255,255,.22);
  --chrome-sel:rgba(255,255,255,.14); --chrome-sel-fg:#FFFFFF;
  --brand-dim:#75C1D9;
    /* In the dark the amber lightens like everything else: dim gold,
       at the same lightness as --head-dim. */
    --head-nota:#BFA671;
    --head-nota-fill:rgba(191,166,113,.17);
  --bar-line:#16262F;
  --bird-op:.10;
  --passero:url("/icona.e2a83984.png");
  --sagome:rgba(255,255,255,.06);
  --velo:rgba(255,255,255,.04);
}

/* scorrimento.css */
/* ============================================================
   SCROLLBARS, ONCE AND FOR EVERYTHING
   ============================================================
   No selector list here: the bare pseudo-element covers everything
   that scrolls, the page included. A new panel has nothing to
   remember, which is the only way this stays consistent.

   The trap that rules a list out: with a LIST of selectors the
   pseudo-element attaches only to the last one.

   The phone wants it thinner (tel/base.css): 8 pixels instead of 10,
   because there the screen is 390 wide and a 10 pixel bar takes a
   hundredth of the usable width.
   ============================================================ */
*{scrollbar-width:thin;scrollbar-color:var(--line-2) transparent}

::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--line-2);border-radius:6px;
  border:3px solid transparent;background-clip:content-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--muted);background-clip:content-box}
::-webkit-scrollbar-corner{background:transparent}

/* app/base.css */
@media (min-width:900px){
/* ============================================================
   THE GROUND OF THE BOARD
   This is not base.css: that one is the ground of the pages that
   SCROLL, where the body has automatic height and the focus ring is
   the brand one. Here the page does not scroll, it is a screen fixed
   inside the window, and the body is a flexible column. Two pages of
   two different natures: putting both things in the same stylesheet
   means switching scrolling off on the sponsor page too.
   ============================================================ */
*{box-sizing:border-box;margin:0;padding:0}

html,body{height:100%;overflow:hidden}

/* The container of the layout: the place where either the board or
   the phone screen is mounted. It has to be INVISIBLE to the
   geometry: it takes what is left over under the header and hands it
   to its children identical, so .shell behaves as if it were still a
   child of the body. */
#schermo{flex:1;min-height:0;display:flex;flex-direction:column}
body{
  display:flex;flex-direction:column;
  background:var(--ground);color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:17px;line-height:1.5;font-weight:400;
  -webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;
}
/* With the match list behind a button, the fixed-screen board holds
   down to much smaller windows. */


button,a{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-decoration:none}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:5px}
.u-num{font-variant-numeric:tabular-nums}

/* The scrollbars live in styles/scorrimento.css, with no lists of
   classes: they hold for everything that scrolls. */

}

/* header.css */
/* ============================================================
   HEADER: stitched to the top, full width, as on the other pages.
   The --gap/--pad rhythm starts here and runs downward.
   ============================================================ */
/* THE HEADER HEIGHT IS --testa, RULE INCLUDED, and it is written here
   because this is where the header is defined. A correction living in
   the sheet of an accessory component only covers the pages that have
   that component.
   box-sizing is already border-box from the reset: the height contains
   the rule instead of adding to it. */
.top{background:var(--head);border-bottom:1px solid var(--head-line);
  height:var(--testa);
  position:sticky;top:0;z-index:20}
.top-in{max-width:1840px;margin:0 auto;height:100%;padding:0 var(--pad);
  display:flex;align-items:center;gap:28px}
.brand{display:flex;align-items:center;gap:11px;flex:none;color:inherit;text-decoration:none}
/* THE WHOLE CREST, AND THE SAME ONE ON EVERY SCREEN.
   The crest settles the balance between bird and lettering inside
   itself, which is what makes a crest a crest. So there is ONE of it,
   identical everywhere, and only its size changes between board and
   phone. 48px tall inside a 64px header: the lettering inside the
   crest stays readable and there is air above and below, so it reads
   as a mark and not as a plug.
   Background and not <img>: see chrome.js. */
.brand .mark{display:block;flex:none;
  height:var(--stemma);width:calc(var(--stemma) * 1.356);
  background:url("/logo-volley-silea.ff7b3ca6.png") center/contain no-repeat}
/* The written name stays in the markup and off the screen: the crest
   already carries it, and the link aria-label says it to anyone who
   cannot see. */
.brand .wm{display:none}
/* Between 900 and ~1050px the eight items do not fit next to the mark:
   instead of breaking the page they scroll inside their own strip.
   min-width:0 because a flex container, left alone, will not be
   squeezed below its own content. */
.nav{display:flex;gap:3px;margin-left:auto;min-width:0;
  overflow-x:auto;scrollbar-width:none}
.nav::-webkit-scrollbar{display:none}
.nav a{padding:9px 15px;border-radius:8px;font-size:15px;font-weight:400;
  color:var(--head-dim);white-space:nowrap;transition:color .15s,background .15s}
.nav a:hover{color:var(--head-fg);background:var(--chrome-btn)}
.nav a.on{color:var(--chrome-sel-fg);font-weight:600;background:var(--chrome-sel)}
/* AN ITEM APART, NOT AN ITEM SINGLED OUT: safeguarding.
   A document the law requires to be published. It sits at the end and
   reads as "another thing", not as the most important one: whoever
   comes for the results does not need the eye pulled over there.

   NO FRAME. In a row of links a frame is an invitation to press, and
   it would make this look like the header main button.
   A RULE IN THE GAP instead: the mark a navigation bar has always used
   to say "from here on it is another group", and it asks nothing of
   anyone. It sits in the margin and not on the link, so the hover veil
   stays one whole shape.
   DIM AMBER, as light as the other items. The tint alone says another
   family; raising the brightness too would be shouting. In the dark it
   lightens along with everything else (--head-nota).

   THE RULE IS THE SAME AMBER and stays one pixel. The frame grey
   (--head-line) is made to detach from a white header and vanishes on
   a black one, while amber shows on both and says the same thing as
   the word it divides. One pixel because it is a mark of separation:
   thicker, it becomes a bar that calls. */
.nav a.bordata{position:relative;margin-left:20px;color:var(--head-nota)}
.nav a.bordata::before{content:"";position:absolute;left:-11px;top:50%;
  transform:translateY(-50%);width:1px;height:18px;
  background:var(--head-nota)}
.nav a.bordata:hover{color:var(--head-nota);background:var(--chrome-btn)}

/* ON ITS OWN PAGE IT STAYS AMBER. "You are here" is the same pill as
   every other item, tinted with the colour this item already has:
   borrowing the blue would fold it back into the group it stays out of
   the rest of the time, exactly while it is open.
   AND THE RULE STAYS. It divides two groups, and the two groups are
   there even from inside the second one. */
.nav a.bordata.on{background:var(--head-nota-fill);color:var(--head-nota);font-weight:600}
.tema{flex:none;width:38px;height:38px;border-radius:9px;border:0;cursor:pointer;
  display:grid;place-items:center;color:var(--head-dim);background:transparent;
  transition:color .15s,background .15s}
.tema:hover{color:var(--head-fg);background:var(--chrome-btn)}
.tema svg{grid-area:1/1;width:19px;height:19px;transition:opacity .2s,transform .2s}
.tema .ico-sole{opacity:0;transform:rotate(-60deg) scale(.7)}
.tema.scuro .ico-sole{opacity:1;transform:none}
.tema.scuro .ico-luna{opacity:0;transform:rotate(60deg) scale(.7)}

/* The hamburger exists only on the narrow layout */
.ham{display:none;width:44px;height:44px;place-items:center;border:0;cursor:pointer;
  background:transparent;color:var(--head-dim);transition:color .15s}
.ham:active{color:var(--head-fg)}
.ham svg{width:20px;height:20px;display:block}

/* Below 900px the header becomes the app one: hamburger on the left,
   mark in the middle, theme on the right. It is the same point where
   the phone shell drops its frame, so moving from page to page the top
   does NOT change under the fingers. */
@media (max-width:899px){
  .top-in{padding:0 4px;gap:0;
    display:grid;grid-template-columns:44px 1fr 44px;align-items:center}
  .ham{display:grid}
  .nav{display:none}
  /* On the phone the WHOLE crest and no lettering: the name is inside
     it, and in a 56px header between hamburger and theme button the
     bird alone with the lettering beside it does not fit without
     shrinking both below the size where they read.
     The crest is THE SAME as the board one, same size: here it just
     sits between two 44px buttons instead of left of a menu. --stemma
     states that size once for both.
     The last pixels at the top and bottom of the crest are the white
     rule the file carries with it (pipeline/tools/trasparenza.js). It
     is part of how the mark is made, and on the near black header it
     is also the only thing detaching its shape from the ground. */
  .brand{justify-content:center}
  .tema{width:44px;height:44px;border-radius:0}
}

/* drawer.css */
/* --- drawer menu, the same one on every page -----------------
   Same measures, weights and wording throughout. Two different menus
   would make moving from one page to another feel like changing
   site. */
.menu{position:fixed;inset:0;z-index:80;
  background:var(--head);color:var(--head-fg);
  display:flex;flex-direction:column;
  opacity:0;pointer-events:none;transition:opacity .2s;
  padding-bottom:env(safe-area-inset-bottom,0px)}
.menu.on{opacity:1;pointer-events:auto}
.menu-top{height:var(--testa);flex:none;display:flex;align-items:center;
  justify-content:space-between;padding:0 4px 0 16px}
/* The whole crest, as in the header this drawer covers: the menu
   opens and the mark stays where it was, at the same size. */
.menu-top .marchio{display:block;flex:none;
  height:var(--stemma);width:calc(var(--stemma) * 1.356);
  background:url("/logo-volley-silea.ff7b3ca6.png") center/contain no-repeat}
.menu .icon{width:44px;height:44px;display:grid;place-items:center;border:0;
  cursor:pointer;background:transparent;color:var(--head-dim)}
.menu .icon svg{width:20px;height:20px;display:block}
/* THE ITEMS ARE THE SCROLLING PART, and flex:1 with min-height:0 is
   what makes that true. Without them a child with overflow does not
   shrink inside a flex column: it grows and spills past its container,
   and on a short screen the footer rule cuts the last item in half. */
/* THE ITEMS SIT IN TWO COLUMNS. Eleven items fit in six rows and all
   land on screen together: the drawer opens and the whole site is
   there, with nothing to drag to reach Contatti.

   EVERY ITEM IS A CELL, all the same size. The grid makes them equally
   wide by construction, and align-items:stretch (the default, so it is
   not written) makes them as tall as the tallest of their row. The
   minimum is sixty-four pixels, above the forty-four a finger needs.

   THE TYPE IS 17. At half the screen width "Calendario" does not fit
   at 24 bold, and a word wrapping inside a cell undoes the grid the
   cell is there to build. */
.menu nav{flex:1;min-height:0;
  padding:18px;overflow-y:auto;
  display:grid;grid-template-columns:1fr 1fr;gap:10px;align-content:start}
.menu nav a{color:var(--head-fg);
  font-size:17px;font-weight:700;letter-spacing:-.02em;
  min-height:64px;padding:12px 14px;
  border:1px solid var(--menu-line);border-radius:12px;
  display:flex;align-items:center;gap:10px}
/* THE ITEM OF THE OPEN PAGE is tinted in three places: text, border
   and a veil of background. Among eleven identical cells one blue word
   between ten white ones is a detail that gets lost, while a tinted
   cell is found without looking for it. */
.menu nav a.on{color:var(--brand);border-color:var(--brand);
  background:color-mix(in srgb, var(--brand) 13%, transparent)}
.menu nav a small{font-size:9px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--head-dim);
  border:1px solid var(--menu-line);border-radius:4px;padding:2px 5px}
/* THE DRAWER FOOTER: who this club is.
   On the board it sits in a strip at the bottom of the screen. Here it
   cannot: below 900px the bottom belongs to the sponsor bar and the
   page does not scroll. So it sits where people look for what the
   screen does not show.

   TRULY AT THE BOTTOM: margin-top:auto pushes it to the last row of
   the column even when few items would leave it hanging halfway. The
   rule separates it from the items, which are large and made to be
   touched; this text is small and made to be read, and with no line
   between them it would read as the last menu item.
   The bottom safe margin already belongs to .menu. */
.menu-piede{
  margin-top:auto;flex:none;
  padding:10px 22px 12px;
  border-top:1px solid var(--menu-line);
  font-size:10.5px;line-height:1.45;color:var(--head-dim);
}
.menu-piede p{margin:0}
.menu-piede p + p{margin-top:3px}
.menu-piede .sep{margin:0 .5em;opacity:.5}

/* SHORT SCREENS. On a 360x640, still around, six rows plus header plus
   footer overflow by twenty pixels and the drawer starts scrolling.
   Everything tightens: shorter cells, less air between them, one pixel
   less type. Fifty-six pixels of cell remain, above the forty-four a
   finger needs. */
@media (max-height:700px){
  .menu nav{padding:14px;gap:8px}
  .menu nav a{min-height:56px;padding:10px 12px;font-size:16px}
}
/* One step further down for the shortest of all: a 360x560, or an
   ordinary phone turned sideways. Fifty pixels are still above the
   forty-four of a finger. It goes no lower: if more room is ever
   needed it scrolls, which by then is the right answer. */
@media (max-height:600px){
  .menu nav{padding:12px;gap:7px}
  .menu nav a{min-height:50px;padding:8px 12px;font-size:15.5px}
}

@media (min-width:900px){ .menu{display:none} }

.toast{position:fixed;left:50%;bottom:30px;z-index:90;
  transform:translate(-50%,10px);
  background:var(--ink);color:var(--panel);
  font-size:13px;font-weight:500;padding:10px 16px;border-radius:10px;
  opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* Safeguarding stands apart down here too, in the dim amber of the
   header. It takes the whole grid width, and its weight stays that of
   the other items: a different item, not a more important one.

   AMBER, not the grey of the chrome: that grey is made to detach from
   a light ground and disappears on the black drawer.
   ON ITS OWN PAGE IT STAYS AMBER: the other selected items turn brand,
   this one already has its colour. */
.menu nav a.bordata{grid-column:1 / -1;
  color:var(--head-nota);border-color:var(--head-nota)}
.menu nav a.bordata.on{color:var(--head-nota);border-color:var(--head-nota);
  background:color-mix(in srgb, var(--head-nota) 13%, transparent)}

/* piede.css */
/* ============================================================
   THE FOOTER: ONE LINE, AT THE BOTTOM OF THE SCREEN
   ============================================================
   Who this club is, by law and by manners: full name, registered
   office, tax code, VAT number and federation code. On one line, in
   small type, in a grey that does not call. This is not text to read,
   it is text to find when looked for: catching the eye would steal
   attention from what the page exists for.

   IT IS FIXED, and that is not an aesthetic choice. On the board most
   pages are window-tall screens that do not scroll (app/base.css:
   html,body{overflow:hidden}), so "the bottom of the page" is not a
   place there. The only page that really scrolls is sponsor, and a
   fixed bar is what that one needs anyway: the footer is not a reward
   for reaching the end of fifteen brands.

   THE BODY GIVES UP THE SPACE, not the footer. A fixed element leaves
   the flow and would pass OVER the content, so the body shortens by
   the same amount and both cases hold: the fixed screen tightens, the
   scrolling page ends higher up. The height lives in a token because
   the footer declares it and the body uses it. Written twice, a change
   to the type size would show up as a covered line or a finger of
   emptiness.

   ON THE PHONE IT IS NOT THERE. Down here the bottom of the screen
   already belongs to the sponsor bar, and a second strip under the
   first would eat screen from a view that has little. The phone footer
   is still to be decided: see the note at the end.
   ============================================================ */

:root{ --piede-h:30px; }

.piede{
  position:fixed;left:0;right:0;bottom:0;z-index:6;
  height:var(--piede-h);
  display:flex;align-items:center;justify-content:center;
  padding:0 16px;
  background:var(--bar);
  border-top:1px solid var(--bar-line);
  /* Not text to read: text to find. Small, in a grey that stays back,
     and never wrapping. One line that on a narrow window shortens with
     an ellipsis instead of becoming two and breaking the strip. */
  /* LINE HEIGHT CANNOT BE 1. At line height one the line is as tall as
     the type, and the descenders (the p of "Sportiva", the g, the q)
     fall OUTSIDE the line: with overflow:hidden above, they get cut in
     half. A comfortable line height keeps them in, and centring the
     line in the strip is the job of align-items, not of the text
     height. */
  font-size:11.5px;line-height:1.45;letter-spacing:.01em;
  color:var(--bar-dim);
  white-space:nowrap;overflow:hidden;
}
.piede p{
  max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* The separator dots: lighter than the text, because all they do is
   separate. The space around them comes from margins, not from two
   spaces written in the markup, which at the end of a line would add
   themselves to the ellipsis. */
.piede .sep{margin:0 .55em;opacity:.5}

/* The body shortens by the height of the footer.
   On fixed screens this tightens the column and nothing ends up under
   the strip; on the scrolling page it is the last piece of document
   that stops higher up. */
body{padding-bottom:var(--piede-h)}

/* ------------------------------------------------------------------
   ON THE PHONE, FOR NOW, NOTHING.
   The bottom of the screen belongs to the sponsor bar, and below 900px
   the page does not scroll (tel/base.css says so in words: "niente
   scorre a livello di pagina"), so there is no "bottom" to put a
   footer in flow. It would go at the end of the scrolling strip,
   inside .scroll, and that strip is mounted by the phone layouts one
   by one: a job to do calmly and in one pass.
   Meanwhile the footer does not show and steals no room: absent beats
   wrong. The natural exception is the sponsor page, a document that
   below 900 really scrolls, where a trailing footer would work on its
   own. Keeping it on one page and not the others would be the worst of
   the three.
   ------------------------------------------------------------------ */
@media (max-width:899px){
  .piede{display:none}
  body{padding-bottom:0}
}

/* THE ONLY ITEM THAT LEADS ANYWHERE. It sits among text nobody
   touches, so it must not shout but must still be recognisable: same
   colour as the rest, underlined on hover. */
.piede a{color:inherit;text-decoration:none}
.piede a:hover,.piede a:focus-visible{text-decoration:underline}

/* app/rail.css */
@media (min-width:900px){
/* ============================================================
   THE HEADER (the two corrections) + THE SPONSOR BAR
   ============================================================ */
/* The header is drawn by header.css, which belongs to every page. On
   this one, though, it has to behave in two ways different from
   there, and neither difference is a matter of taste:

   1. IT IS NOT STUCK. The board is a fixed screen: nothing scrolls
      and a sticky has nothing to follow. Below 960px, however, the
      page really does scroll again (flow mode, at the bottom of
      pages/risultati.css) and there a sticky shows: the header stays
      glued to the top while the rest scrolls away.

   2. IT IS --testa TALL IN FULL, border included. header.css puts the
      min-height on the CONTENT and the border adds to it: one pixel
      more across the whole width, which pushes down everything that
      comes after. With box-sizing:border-box the height on the band
      includes the hairline, and the content stays one pixel lower.
      The min-height has to go off along with it, otherwise it wins:
      half a pixel, but it is half a pixel on the mark, the entries
      and the theme button, that is on the whole top of the page.
      THE HEIGHT IS SPOKEN BY THE TOKEN and not by a number typed
      here. This sheet arrives after header.css, so a number typed
      here wins over the token: the crest is left with four pixels
      above and four below, wedged between the two borders. A second
      place where the same measure is written is a second place to
      remember.

   It sits here and no higher up because it has to arrive AFTER
   header.css. */
.top{position:static;flex:none;height:var(--testa)}
.top-in{height:100%;min-height:0}

/* THE BAR HANGS FROM THE HEADER, it does not float below it.
   The two do the same job (staying at the top and not scrolling)
   and set apart they read as two bands of navigation, one inside the
   other.
   So they touch: no gap above, the top border of the bar is the
   bottom border of the header, and the corners go square where the
   two meet. It is the same way a round's cards attach to the day bar
   on the phone (tel/gara.css): the piece above acts as the border of
   the piece below.
   Below, instead, the gap stays: that is where the content of the
   page begins, and that is another matter. */
.railwrap{flex:none;max-width:1840px;width:100%;margin:0 auto;
  padding:0 var(--pad)}
/* A padding of 5, and the ten pixels it spares all go to the plate:
   the bar stands 68px tall and the logo takes the largest share of
   it. Horizontal room is not scarce, so the gap stays 10. */
.rail{background:var(--panel);border:1px solid var(--edge);
  border-top:0;border-radius:0 0 14px 14px;
  padding:5px;display:grid;grid-template-columns:repeat(6,1fr);gap:10px;
  --h:48px}   /* usable height of the logo inside the plate */
/* The plate stays white at night too. The sponsors' files carry a
   white background baked in (none of them has an alpha channel): on a
   dark panel that shows as fifteen white rectangles. A plate fixed to
   white = the file's background disappears into the plate. */
.slot{height:56px;border-radius:9px;background:#fff;border:1px solid var(--line);
  display:grid;place-items:center;overflow:hidden;padding:0 12px;
  transition:border-color .16s,box-shadow .16s}
.slot:hover{border-color:var(--brand);box-shadow:0 1px 7px rgba(3,119,189,.18)}
/* --k evens out the AREA between logos of very different proportions:
   left alone, a 4:1 wordmark as tall as a square logo weighs three
   times as much. object-fit scales back when the logo is wider than
   the plate, so the proportion is never distorted. */
.slot img{display:block;width:100%;height:calc(var(--h) * var(--k,1));
  object-fit:contain;object-position:center;transition:opacity .42s ease}
.slot img.out{opacity:0}
.slot img.scuro{border-radius:3px}   /* logos with a dark plate keep clear of the corners */

}

/* app/griglia.css */
@media (min-width:900px){
/* ============================================================
   THE GRID
   ============================================================ */
.shell{
  flex:1;min-height:0;overflow:hidden;
  max-width:1840px;width:100%;margin:0 auto;
  /* above it is a gap between panels, below it is the frame of the
     page: this way the bottom margin matches the side ones */
  padding:var(--gap) var(--pad) var(--pad);
  display:grid;grid-template-columns:284px minmax(0,1fr) 400px;gap:var(--gap);
}
.side{min-height:0;min-width:0;display:flex;flex-direction:column}
.side .panel{flex:1}
/* the hero is as tall as its content (constant), the rest goes to the list */
.centre{display:grid;grid-template-rows:auto minmax(0,1fr);gap:20px;min-height:0;min-width:0}
.aside{display:grid;grid-template-rows:minmax(0,1fr);min-height:0;min-width:0}
/* Below 1400px the centre would drop under the ~594px the box score
   needs, and the names would break one letter at a time. Better to
   take the table away and call it back from a button in the bar. */
@media (max-width:1399px){
  .shell{grid-template-columns:284px minmax(0,1fr)}
  .aside{display:none}
  .side-links .side-tbl{display:flex}
}
@media (max-width:960px){
  .shell{grid-template-columns:minmax(0,1fr);padding-bottom:26px}
  .aside{display:grid}      /* in a single column there is room for it again */
  .side-links .side-tbl{display:none}
}

.panel{background:var(--panel);border:1px solid var(--edge);border-radius:14px;
  display:flex;flex-direction:column;min-height:0;overflow:hidden}
/* dark bar */
/* THE BAR IS 38 HIGH, everywhere. Every extra pixel of dark band is
   paid four times over on a board with four panels: sixteen more each
   are sixty pixels of screen spent on frame instead of on content.
   It is a MINIMUM, not a height: a bar with something taller inside
   (the matchday buttons, which are 38 round) grows by itself. */
.p-head{flex:none;background:var(--bar);color:var(--bar-fg);
  border-bottom:1px solid var(--bar-line);
  padding:0 20px;min-height:38px;display:flex;align-items:center;justify-content:space-between;gap:14px}
/* THE PANEL TITLE IS IN THE SAME FACE AS EVERYTHING ELSE. The brand
   face looks good on a sign, but at 13px in spaced uppercase its
   squared letters read one character at a time instead of one word at
   a time, and a panel title is read in passing: it is the thing that
   says WHERE YOU ARE, and if it costs attention it has already
   failed.
   The brand face, on this site, lives inside the crest. */
.p-head .t{font-size:13px;font-weight:600;letter-spacing:.1em;text-transform:uppercase}
.p-head .t.dim{color:var(--bar-dim);font-weight:400}

}

/* app/lato.css */
@media (min-width:900px){
/* ============================================================
   THE SIDE BAR
   ============================================================ */
.season{width:100%;display:flex;align-items:center;justify-content:space-between;
  padding:16px 20px;border-bottom:1px solid var(--line);flex:none;text-align:left;
  background:var(--zebra)}
/* Same story as .rlabel (see app/giornate.css): the row "STAGIONE"
   holds a single 11px child, and this line keeps it 16.5 tall instead
   of 25.5. Without it the whole side bar goes down nine pixels. The
   container has no text of its own: declaring 11px on it shows
   nowhere. */
.season > span:first-child{font-size:11px}
.season b{font-size:19px;font-weight:600;letter-spacing:-.01em}
.season .c{font-size:11px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
/* The list of seasons: a little panel that opens OVER the content,
   like the table's settings menu on mobile. It is not a band in the
   column, otherwise opening it would push the tree of competitions
   down. It lives inside .seasonwrap so it hooks onto the bottom of
   the button without the height having to be guessed by hand. */
.seasonwrap{flex:none;position:relative}
.season .c:last-child{display:inline-block;transition:transform .16s}
.season.on .c:last-child{transform:rotate(180deg)}
.seasons{
  position:absolute;top:100%;left:10px;right:10px;z-index:30;margin-top:-4px;
  background:var(--panel);border:1px solid var(--line-2);border-radius:11px;
  box-shadow:var(--shadow);
  padding:5px;display:flex;flex-direction:column;gap:2px;
  opacity:0;transform:translateY(-6px);pointer-events:none;
  transition:opacity .16s,transform .16s;
}
.seasons.on{opacity:1;transform:none;pointer-events:auto}
/* THE SEASON SITS AT THE TOP IN ALL THREE PAGES, and the little panel
   opens downwards.
   It is the simplest truth: choosing the year is the FIRST decision,
   and everything below it (competitions, teams to tick, team to open)
   belongs to that year. Three side bars that behave the same way.
   Anchored at the top, the little panel also stays inside the box:
   hooked to the bottom of a button at the foot of the panel it would
   fall outside it (overflow:hidden) and vanish without a word. */
.seasons button{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 12px;border-radius:8px;text-align:left;
  font-size:15px;font-weight:400;color:var(--ink-2);transition:background .14s}
.seasons button:hover{background:var(--zebra)}
.seasons button.on{background:var(--me-fill);font-weight:600;color:var(--brand-2)}
.seasons .tag{font-size:9.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);border:1px solid var(--line-2);border-radius:4px;padding:2px 6px}
/* Three tabs at the top of the tree of competitions. 1fr columns: the
   width is the same for all three, it does not depend on how long the
   word is. minmax(0,1fr) because otherwise the content dictates the
   minimum and "PLAYOFF" takes more room than "COPPE". */
.ttabs{flex:none;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:4px;padding:10px 12px 0}
.ttabs button{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  padding:9px 4px;border-radius:9px;min-width:0;
  border:1px solid transparent;background:var(--zebra);
  font-size:10px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);transition:background .14s,color .14s,border-color .14s;
}
.ttabs button:hover{background:var(--sunken);color:var(--ink-2)}
.ttabs button.on{background:var(--me-fill);border-color:var(--brand);color:var(--brand-2)}
/* The other competitions of the same team sit INSIDE the selected
   entry, as a third row, side by side. */
.coll{display:flex;flex-wrap:wrap;gap:5px;margin-top:8px}
.chip-c{display:inline-block;padding:4px 9px;border-radius:6px;
  border:1px solid var(--line-2);background:var(--panel);color:var(--brand-2);
  font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  cursor:pointer;transition:background .14s,border-color .14s}
.chip-c:hover{background:var(--zebra);border-color:var(--brand)}

/* a section with no data: switched off. After :hover, otherwise it
   loses on equal specificity and lights up again under the mouse. */
.ttabs button[disabled],
.ttabs button[disabled]:hover{
  background:transparent;border-color:transparent;color:var(--faint);
  opacity:.45;cursor:default;
}
.ttabs svg{width:17px;height:17px;flex:none}
.ttabs .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.tree{flex:1;min-height:0;overflow-y:auto;padding:14px 12px}
.tree .grp{padding:16px 10px 8px;font-size:11px;font-weight:500;
  letter-spacing:.13em;text-transform:uppercase;color:var(--faint)}
.tree button{width:100%;display:flex;align-items:center;gap:13px;padding:11px 12px;
  border-radius:10px;text-align:left;font-size:15.5px;font-weight:400;color:var(--ink-2);
  transition:background .14s,color .14s}
/* name + group on two lines, as in the mobile selector */
.tree .txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.tree .txt b{font-size:15px;font-weight:500;letter-spacing:-.005em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tree .txt small{font-size:12px;font-weight:400;color:var(--faint);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* WHO PLAYS IT, between the tournament and the group. The tournament
   and the group say WHERE it is played, never who: with eleven teams
   of the club across five different tournaments, "U16 Provinciale /
   Girone C" does not say whether it is the LagoVerde or the MGI
   Tools, and those are two different teams with two different tables.
   It sits in the middle because that is the running order: the
   tournament, the team, and at the bottom the detail of the group.
   The tone falls from line to line (ink, half tone, faint) and with
   the entry selected it goes up one step all together, so the running
   order stays the same. */
.tree .txt .chi{font-size:12.5px;font-weight:500;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tree button.on .txt .chi{color:var(--ink-2)}
/* MORE THAN ONE ENTRY INSIDE ONE ITEM. A team can be entered several
   times under different names (ui/iscrizioni.js): the item names them
   all, and each name keeps its own tournaments attached below it. The
   gap between one pair and the next is wider than the leading,
   otherwise four rows in a row read as a single list and which
   subtitle belongs to whom is lost. */
.tree .isc{min-width:0;display:flex;flex-direction:column;gap:1px}
.tree .isc + .isc{margin-top:7px}
.tree button.on .txt b{font-weight:600;color:var(--brand-2)}
.tree button.on .txt small{color:var(--muted)}
.tree button[disabled] .txt small{color:var(--faint)}
.tree button:hover:not([disabled]){background:var(--zebra);color:var(--ink)}
/* Selection: the same language that marks the Silea out in the table:
   a faint veil, a bar on the left, brand-coloured text.
   No solid cyan: in the dark the white on top of it does not read. */
.tree button.on{
  background-image:linear-gradient(var(--me-fill),var(--me-fill));
  box-shadow:inset 3px 0 0 var(--brand);
  color:var(--brand-2);
}
.tree button[disabled]{color:var(--faint);cursor:default}
/* THE BADGE IS IN THE BRAND FACE. This is the right place for a
   signage face: it is not text to be read but a MARK, one, two or
   three letters inside a small square, recognised by their shape
   before their letters, the way a number plate is recognised.
   D, 2D, U16: they have to tell each other apart at first glance in a
   column of six entries, and that is exactly what a squared, narrow
   face does better than a text one.
   On panel titles the same face is wrong, and for the opposite
   reason: there they are words, and words are read.
   NARROW FOR SIZE TOO: "U16" in a 30 square set in a text face
   reaches the edge. This one fits with air around it.
   Weight 400 everywhere, selected too: the face exists in a single
   cut, and asking for a fatter one means the browser thickens the
   outlines of this one. That the entry is chosen is already said by
   the solid background and the colour, which are two signals. */
.tree .bdg{flex:none;width:30px;height:30px;border-radius:8px;background:var(--sunken);
  color:var(--muted);display:grid;place-items:center;
  font-family:var(--titoli);font-size:12px;font-weight:400;letter-spacing:.02em}
.tree button.on .bdg{background:var(--brand);color:var(--on-brand)}
.tree .soon{margin-left:auto;font-size:10px;font-weight:500;letter-spacing:.07em;
  text-transform:uppercase;color:var(--faint);border:1px solid var(--line);
  border-radius:5px;padding:2px 6px}
/* NO BACKGROUND AND NO HAIRLINE. There is a single button down here,
   and a band with a tone of its own would be a frame around nothing:
   a strip of a different colour at the foot of the panel, which is
   the first thing the eye finds coming down the bar. The button
   stands apart on its own, having its own border and its own colour. */
/* THE FOOT IS EMPTY NEARLY ALWAYS, AND WHEN EMPTY IT TAKES UP
   NOTHING. The button below lives only between 961 and 1399px: above
   that there is the column with the table and the button is not
   needed (app/griglia.css). With the padding on the container there
   is a white strip twenty-five pixels tall under the tree all the
   same, and what one sees is not an empty container: it is the panel
   failing to reach the bottom.
   THE SPACE BELONGS TO THE BUTTON, not to the container that holds
   it: that way it appears and disappears with it, without a second
   @media repeating the breakpoint, and without depending on which
   sheet is loaded after which. */
.side-links{padding:0;flex:none;display:flex;flex-direction:column;gap:9px}
.side-cal{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:13px 14px;border-radius:10px;font-size:14.5px;font-weight:600;
  color:var(--brand-2);border:1px solid var(--line-2);
  transition:background .14s,border-color .14s}
.side-cal:hover{background:var(--sunken);border-color:var(--brand)}
.side-tbl{display:none;width:auto;margin:12px}
.side-cal .arr{color:var(--brand)}

}

/* app/giornate.css */
@media (min-width:900px){
/* The file is called giornate.css and the section HERO: the head of
   the result panel and the round selector are the same band, and the
   strip below is part of it. */
/* ============================================================
   HERO
   The arrows sit in FIXED grid columns: changing round changes the
   text, not them. The chip's area is fixed too, so "VITTORIA" and
   "DA GIOCARE" move nothing.
   ============================================================ */
/* three fixed columns: the chip lives in the result panel, the
   arrows stay nailed to their place */
.hero-head{display:grid;grid-template-columns:38px minmax(0,1fr) 38px;
  align-items:center;gap:16px;min-height:58px}
.rnav{width:38px;height:38px;border-radius:9px;display:grid;place-items:center;
  color:var(--bar-fg);background:var(--chrome-btn);transition:background .14s}
.rnav:hover:not([disabled]){background:var(--chrome-btn-h)}
.rnav[disabled]{opacity:.25;cursor:default}
.rnav svg{width:17px;height:17px}
/* THE font-size HERE IS NOT DECORATION, IT IS HEIGHT.
   A line that holds no text of its own, but only an inline child,
   still counts the block's "strut", and inherited that strut is
   17px x 1.5 = 25.5: the row with the date ("10–11 ottobre", 13px)
   stands at 25.5 instead of 19.5 and the round label slides three
   pixels up and three down. Declaring 13px on the container puts the
   strut at the size of what the row really holds, and changes nothing
   else because the two children declare their own size. */
.rlabel{font-size:13px;text-align:center;min-width:0;overflow:hidden}
.rlabel b{font-size:17px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  white-space:nowrap;display:block}
.rlabel span{font-size:13px;font-weight:400;color:var(--bar-dim);white-space:nowrap}

/* the only exception to the weight scale (600 at most): the result
   tag is a plate, not running text, and it has to stand out */
.chip{flex:none;padding:7px 13px;border-radius:8px;background:var(--brand);color:var(--on-brand);
  font-size:12.5px;font-weight:900;letter-spacing:.09em;white-space:nowrap}
.chip.ghost{background:var(--sunken);color:var(--muted);border:1px solid var(--line)}

/* "safe center": centred, but when the rounds do not fit the width it
   does not cut off the first ones: scrolling stays reachable */
.strip{flex:none;display:flex;align-items:center;gap:5px;padding:10px 18px;
  justify-content:center;justify-content:safe center;
  border-bottom:1px solid var(--line);background:var(--zebra);
  overflow-x:auto;scrollbar-width:none}
.strip::-webkit-scrollbar{display:none}
.gd{flex:none;min-width:34px;height:34px;padding:0 9px;border-radius:8px;font-size:14px;
  font-weight:400;color:var(--faint);font-variant-numeric:tabular-nums;
  transition:background .14s,color .14s}
.gd:hover{background:var(--sunken);color:var(--ink)}
.gd.done{color:var(--ink-2)}
.gd.on{background:var(--brand);color:var(--on-brand);font-weight:600}
/* In the cups the strip carries the ROUNDS by name, not by number:
   the plates are as wide as the word, not square like the matchdays. */
/* the button that crosses between league and final phase: it stands
   apart from the matchdays, it is not one of them */
.gd.salto{min-width:0;margin-left:8px;padding:0 13px;
  font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brand-2);background:var(--zebra);border:1px dashed var(--line-2)}
.gd.salto:first-child{margin-left:0;margin-right:8px}
.gd.salto:hover{background:var(--sunken);border-color:var(--brand);color:var(--brand)}
.gd.fase{min-width:0;padding:0 14px;font-size:12.5px;font-weight:500;letter-spacing:.04em;
  text-transform:uppercase;white-space:nowrap}
/* An open phase: the pill does not change its nature, it just grows
   longer. The matchdays sit INSIDE it, veiled over the solid brand
   colour, so the plate keeps reading as selected and the matchdays as
   its content. */
.gd.fase.aperta{display:inline-flex;align-items:center;gap:3px;
  padding:0 5px 0 14px;cursor:default}
.gd.fase.aperta .et{font-size:12.5px;font-weight:500;letter-spacing:.04em;
  text-transform:uppercase;white-space:nowrap;margin-right:7px}
/* Unselected: no background, they lean on the pill and stay back.
   Selected: colours FLIPPED with respect to the pill - light
   background and brand-coloured text. Two veils close to each other
   give no signal of choice; flipping does. */
.gd.fase.aperta .sub{
  height:26px;min-width:28px;padding:0 9px;border-radius:6px;
  font-size:12px;font-weight:500;white-space:nowrap;
  color:var(--on-brand);background:transparent;opacity:.82;
  transition:background .14s,color .14s,opacity .14s;
}
.gd.fase.aperta .sub:hover{opacity:1;background:var(--brand-dim)}
.gd.fase.aperta .sub.qui{
  opacity:1;background:var(--panel);color:var(--brand);font-weight:600;
}

}

/* app/tabellino.css */
@media (min-width:900px){
/* ============================================================
   BOX SCORE, MARGIN CHART, COUNTDOWN
   The three contents that take turns inside the result panel and
   inside the match dialog, always at the same height.
   ============================================================ */
/* box score: the sets lined up in columns on the team rows. Five
   columns always kept for them. */
.tab{display:flex;flex-direction:column;gap:8px}
/* the result right after the name, the set detail on the right, as
   in the list of the other matches */
.tabhead,.trow{display:grid;grid-template-columns:38px minmax(0,1fr) 56px repeat(5,36px);
  gap:10px}
.tabhead{align-items:center}
/* Everything centred vertically, with no corrections.
   The gap between the optical centre of the figures and the centre of
   the box is (ascender − descender)/2 − cap-height/2: with Segoe UI
   that makes −0.014em, which is half a pixel at 36px. */
.trow{align-items:center}
.tabhead span{font-size:11px;font-weight:500;color:var(--faint);text-align:center}
.tabhead .sp{grid-column:1/4}
.trow .cr{width:38px;height:38px;border-radius:50%;background:var(--sunken);
  border:1px solid var(--line);color:var(--muted);display:grid;place-items:center;
  font-size:12px;font-weight:500}
.trow.me .cr{background:linear-gradient(145deg,var(--accent),var(--brand));
  border-color:var(--brand);color:var(--on-brand)}
/* NEVER truncate: FIPAV names carry the sponsor inside them. If it
   does not fit on one line it wraps, it does not end in an ellipsis. */
.trow .nm{min-width:0;font-size:19px;font-weight:400;color:var(--ink-2);
  line-height:1.25;overflow-wrap:anywhere}
.trow.me .nm{color:var(--brand-2);font-weight:600;text-transform:uppercase;letter-spacing:.02em}
/* ============================================================
   THE SPARROW AND THE NAME, IN THE RESULT CARD
   ============================================================
   THE SILEA'S CREST IS THE SPARROW. It is the same figure that flies
   behind the card and that sits on the browser tab, so it is not a
   new sign, and whoever meets it here has already seen it elsewhere.
   IT HOLDS EVERYWHERE, and not only inside the result card. The
   sparrow is in the table, in the other matches, in the dialog: on a
   page where the Silea appears three times, one team gets one sign,
   and three different signs are worse than a small sparrow. The small
   sparrow is recognised all the same (it is the silhouette that
   tells it apart, not the detail of the feathers) and above all it
   is ALWAYS THE SAME SIGN.
   The sizes are left alone: every list keeps its own, so nothing
   moves. What changes is what stands inside the circle.
   The initials stay written and turn TRANSPARENT instead of going
   away: whoever reads the page by voice keeps hearing them, and for
   them the sparrow does not exist.
   The border turns transparent and not zero: with box-sizing the
   border takes part in the measurement, and dropping it widens the
   sparrow against the opponents' crests standing beside it.
   EVERY LIST CALLS A ROW "OURS" IN ITS OWN WAY (.trow.me, .cr.vs,
   tr.me, .cr.me) so the rule is repeated once per sheet instead of
   written once with four selectors: the sheets load in different
   groups from page to page, and a selector written in a sheet that
   page does not load does not exist.

   THE SILEA'S NAME STAYS IN EVERYBODY'S FACE. In the card the two
   names sit one under the other two lines apart, and in two different
   faces they read as two things of a different nature, a sign and a
   piece of data, instead of as two teams.
   That the row is ours is already said by the colour, the weight and
   the sparrow alongside, which are three signals and enough.
   ============================================================ */
.trow.me .cr{background:var(--passero) center/contain no-repeat;
  border-color:transparent;color:transparent}

.trow .sp{font-size:17px;font-weight:400;color:var(--muted);text-align:center;
  font-variant-numeric:tabular-nums}
.trow .sp.won{color:var(--ink);font-weight:600}
/* the sets the Silea wins take the team colour, not the white */
.trow.me .sp.won{color:var(--brand-2)}
.trow .sp.na{color:var(--line-2)}
.trow .sc{font-size:36px;font-weight:600;letter-spacing:-.03em;text-align:center;
  line-height:1;font-variant-numeric:tabular-nums;color:var(--ink-2)}
.trow.me .sc{color:var(--brand-2)}

/* margin chart. The rows share the room: 3 or 5 sets, same height */
.ch-head{flex:none;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:12px;
  padding-bottom:11px;border-bottom:1px solid var(--line)}
.ch-side{font-size:12.5px;font-weight:500;color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ch-side.r{text-align:right}
.ch-lbl{font-size:10.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--faint)}
.ch-rows{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;padding:4px 0}
/* no column with the set score: it is already in the box score on the
   left, and without it the track gains ~74px of run. */
.ch-row{flex:1 1 0;min-height:24px;max-height:42px;
  display:grid;grid-template-columns:26px 1fr 58px 40px;align-items:center;gap:14px}
.ch-sc{font-size:14px;font-weight:400;color:var(--faint);text-align:right;font-variant-numeric:tabular-nums}
.ch-n{font-size:12.5px;font-weight:400;color:var(--faint)}
.ch-track{position:relative;height:14px;border-radius:7px;background:var(--sunken);
  border:1px solid var(--line-2)}
/* the centre line has to BE SEEN: it is the mark the bar starts from */
.ch-track::before{content:"";position:absolute;left:50%;top:-4px;bottom:-4px;
  width:2px;margin-left:-1px;background:var(--faint);border-radius:1px}
.ch-bar{position:absolute;top:-1px;bottom:-1px;display:block;background:var(--line-2);
  animation:chgrow .42s cubic-bezier(.2,.8,.2,1) both}
.ch-bar.me{background:var(--brand)}
.ch-bar.l{border-radius:6px 0 0 6px;transform-origin:right center}
.ch-bar.r{border-radius:0 6px 6px 0;transform-origin:left center}
@keyframes chgrow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.ch-d{font-size:15px;font-weight:600;text-align:right;color:var(--ink-2);font-variant-numeric:tabular-nums}
.ch-tot{flex:none;display:flex;align-items:center;justify-content:space-between;
  padding-top:12px;border-top:1px solid var(--line);font-size:13.5px;color:var(--muted)}
.ch-tot b{font-size:18px;font-weight:600;color:var(--ink)}


}

/* app/modale.css */
@media (min-width:900px){
/* ============================================================
   THE DIALOG
   ============================================================ */
dialog{border:1px solid var(--edge);padding:0;margin:auto;background:var(--panel);color:var(--ink);
  border-radius:16px;max-width:min(1120px,94vw);width:100%;max-height:88vh;
  overflow:hidden;box-shadow:var(--shadow)}
dialog[open]{display:flex;flex-direction:column}
dialog::backdrop{background:var(--scrim)}
.dlg-head{padding:18px 24px;background:var(--bar);color:var(--bar-fg);flex:none;
  display:flex;align-items:center;justify-content:space-between;gap:18px}
.dlg-head b{font-size:19px;font-weight:600;letter-spacing:-.01em;display:block}
.dlg-head span{font-size:13.5px;font-weight:400;color:var(--bar-dim)}
.dlg-x{width:36px;height:36px;border-radius:9px;display:grid;place-items:center;
  color:var(--bar-fg);background:var(--chrome-btn);transition:background .14s}
.dlg-x:hover{background:var(--chrome-btn-h)}
.dlg-body{overflow:auto;min-height:0}
.dlg-body .tbl td{height:50px}
.dlg-body .tbl th,.dlg-body .tbl td{white-space:nowrap}
.dlg-body .tbl th:first-child,.dlg-body .tbl td:first-child{padding-left:18px}
.dlg-body .tbl th:last-child,.dlg-body .tbl td:last-child{padding-right:20px}
.dlg-body .tbl .c-team{min-width:220px}
.form-mini{display:flex;gap:5px;justify-content:flex-end}
.form-mini i{width:10px;height:10px;border-radius:50%;display:block}
.form-mini i.w{background:var(--up)}
.form-mini i.l{background:var(--down)}

/* button that takes the list's place when there is not enough room */
.mfew{flex:1;min-height:0;display:grid;place-items:center;padding:12px}
.mfew button{
  display:inline-flex;align-items:center;gap:10px;padding:13px 20px;border-radius:10px;
  font-size:13px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
  color:var(--brand-2);border:1px solid var(--line-2);background:var(--zebra);
  transition:background .14s,border-color .14s;
}
.mfew button:hover{background:var(--sunken);border-color:var(--brand)}

/* the dialog with every match of the round */
#rdlg{max-height:min(88vh,760px)}
#rdlg .dlg-body{min-height:0;padding:0}
#rdlg .mrow{border-bottom:1px solid var(--line)}
#rdlg .mrow:last-child{border-bottom:0}

/* a rest round */
.hero-riposo{height:100%;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:12px;padding:20px;text-align:center}
/* The sparrow, as wherever the Silea appears: here it is 52 across,
   because it is the only thing inside an empty panel. */
.hero-riposo .cr{width:52px;height:52px;border-radius:50%;
  background:var(--passero) center/contain no-repeat;
  border-color:transparent;color:transparent;display:grid;place-items:center;font-size:15px;font-weight:600}
.hero-riposo b{font-size:19px;font-weight:600;letter-spacing:-.01em}
.hero-riposo .sub{font-size:14px;color:var(--muted)}

/* playoff band and draw (youth leagues with a fixed number of sets) */
.tbl tr.po .c-pos{border-left-color:var(--accent)}
.form-mini i.d{background:var(--faint)}

/* ============================================================
   THE MATCH DIALOG
   ============================================================ */
/* FIXED HEIGHT, set on the 5-set chart, the tallest content of the
   three tabs. The others scroll inside this measure.
   86 head + 149 score + 63 tabs + 343 chart = 641, +10 of air */
#mdlg{height:min(88vh,651px)}
#mdlg .dlg-body{flex:1;min-height:0}
/* the score block reuses the same box score as the main screen: same
   job, so the two cannot drift apart */
.mdlg-score{flex:none;padding:20px 26px;border-bottom:1px solid var(--line)}

.mtabs{flex:none;display:flex;gap:4px;padding:12px 26px;border-bottom:1px solid var(--line);
  background:var(--zebra)}
.mtabs button{padding:9px 16px;border-radius:9px;font-size:13px;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted);transition:background .14s,color .14s}
.mtabs button:hover{color:var(--ink);background:var(--sunken)}
.mtabs button.on{background:var(--brand);color:var(--on-brand)}

.mchart{padding:22px 26px}
.mchart .ch-rows{flex:none;padding:14px 0}
.mchart .ch-row{flex:none;height:40px;max-height:none}

.vuoto{padding:44px 26px;display:flex;flex-direction:column;align-items:center;
  gap:8px;text-align:center}
.vuoto b{font-size:16px;font-weight:600;color:var(--ink-2)}
.vuoto span{font-size:14px;color:var(--faint)}

.story{padding:22px 26px;max-width:74ch;display:flex;flex-direction:column;gap:16px}
.story h4{font-size:19px;font-weight:600;letter-spacing:-.015em;line-height:1.3;color:var(--ink)}
.story p{font-size:15.5px;line-height:1.65;color:var(--ink-2)}
.story .by{font-size:12.5px;color:var(--faint);border-top:1px solid var(--line);padding-top:14px}

}

/* app/gara.css */
@media (min-width:900px){
/* ============================================================
   THE MATCH CARD: the day column, and not only
   ============================================================
   Two pages draw a match (the calendar in the day column, the
   homepage in the first team's panel) and the markup already lives
   in a single place (ui/gara.js): the sheet follows it, so the two
   pages do not show the same card out of two sheets bound to drift
   apart.

   The measurements speak of the calendar's day column, because that
   is where they are decided, and they stay those: six cards that fit
   without scrolling are a promise of that page, not of this one.
   ============================================================ */

/* ============================================================
   THE DAY COLUMN
   One card per match, and six of them fit without scrolling: six is
   the worst day of 2025/26, and it is the reason this is a column and
   not a bubble hanging off the cell.
   ============================================================ */
.daybox{flex:1;min-height:0;overflow-y:auto}
/* 10 of padding and not 12, and it is not a cosmetic touch: the two
   team rows and the time are worth some ten pixels a card, and the six
   of the worst day fit without scrolling only with those pixels taken
   back from here. Six that fit is the promise of this column (see
   above). */
.dcard{display:grid;grid-template-columns:74px minmax(0,1fr);align-items:center;gap:13px;
  padding:10px 16px;border-bottom:1px solid var(--line)}
.dcard:last-child{border-bottom:0}
.dcard.casa{box-shadow:inset 3px 0 0 var(--brand)}
.dcard.via{box-shadow:inset 3px 0 0 var(--line-2)}
/* The cards that open say so under the mouse. The card of a match
   still to be played does not open and does not say so: there is no
   box score behind it, and on /risultati/ the same rule holds: the
   «Dettagli partita» button appears only once the match is over. */
.dcard.apre{cursor:pointer;transition:background .14s}
.dcard.apre:hover{background:var(--zebra)}

/* THE STRIP DOWN THE LEFT OF THE CARD.
   The score sits at the end of the two team rows, where it sits in
   the result card, and here there is room for the three things that
   are looked at first: what time it is played, how it ended, and
   whether we stay or we travel. */
.dwhen{display:flex;flex-direction:column;align-items:center;gap:3px}
.dwhen b{font-size:19px;font-weight:600;color:var(--ink);letter-spacing:-.01em;line-height:1.15}
/* The result in words. LIGHT green and red, not the solid ones:
   beside two rows of names a saturated fill pulls the eye away from
   exactly what is being read. The draw is neutral: it happened, but
   it is neither one thing nor the other.
   nowrap because the column is 74px wide and «SCONFITTA» on two lines
   makes the card fifteen pixels taller, that is one of the six of the
   worst day. */
.desito{padding:1px 6px;border-radius:5px;white-space:nowrap;
  font-size:9px;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.dcard.vinta .desito{background:var(--up-fill);color:var(--up)}
.dcard.persa .desito{background:var(--down-fill);color:var(--down)}
.dcard.pari .desito{background:var(--line-2);color:var(--ink)}
.dsede{display:flex;align-items:center;gap:4px;
  font-size:9.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
.dcard.casa .dsede{color:var(--brand-2)}
.dsede .emo{font-size:12px;line-height:1}

.dinfo{min-width:0;display:flex;flex-direction:column;gap:2px}
/* THE TITLE OF THE CARD IS THE COMPETITION, and the round sits at the
   end of the same line: it is the top of a stage of the run
   (app/percorso.css .cima), name on the left and when on the right. */
.dcima{display:flex;align-items:center;justify-content:space-between;gap:8px}
/* THE COMPETITION PLATE IS THE ONE FROM HOME (.ca-eti in
   app/home.css): brand colour and the text on it. The tournament is
   the first thing that tells one match from another (a cup match and
   a league match look alike in everything else) and on the homepage
   a solid pill already says so. Two ways of announcing the same thing
   on two pages of the same site are two grammars to keep in
   agreement, and the stronger one is already chosen.
   OUTLINED AND NOT FILLED. A fill says its piece where the plate is
   alone on a screen; in a column of six cards it makes six brand
   blots in a row, and the eye lands on them instead of on the team
   names, which are what one is looking for. The outline says the same
   thing in a lower voice: same shape, same place, same colour. Only
   the border and the word carry it rather than the background.
   The padding goes down by one pixel per side: the border takes its
   own, and this keeps the plate from growing.

   The min-width:0 and the ellipsis stay: "3ª Divisione U16" fits
   inside a 400px column, "U16 Elite Provinciale" with a long phase
   name does not. */
.dcomp{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  border:1px solid var(--brand);border-radius:999px;padding:3px 10px;
  font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--brand)}
.dgio{flex:none;white-space:nowrap;font-size:11px;font-weight:400;color:var(--faint)}
/* THE TWO TEAMS, THE HOME SIDE ON TOP, THE SCORE AT THE END OF EACH
   ROW: the result card of /risultati/, in miniature. Ours stands
   out: brand colour and uppercase, which is the language the site
   uses to say "this is us" in the table and in the box score. Never
   smaller nor lighter than the opponent: same size, one step more of
   weight. This way who is hosting reads without looking at the icon
   in the column alongside, and when our row is the one BELOW it means
   we are away. */
.drow{display:flex;align-items:baseline;gap:10px}
/* THE ELLIPSIS AND NOT THE WRAP. The federation's names reach thirty
   characters and the column holds about twenty: wrapping, the card
   changes height from one match to the next and the six of the worst
   day no longer fit in the column. */
.dteam{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:14.5px;font-weight:400;line-height:1.25;color:var(--ink-2)}
.dteam.noi{font-weight:600;color:var(--brand-2);text-transform:uppercase;letter-spacing:.02em}
/* The score column NEVER narrows, so the name does not run into it,
   and it is there before the first whistle too, with the dash: were
   it to appear only once the match is played, the two rows would
   shorten the moment a result arrives. */
.dsc{flex:none;min-width:13px;text-align:right;
  font-size:15px;font-weight:600;line-height:1.25;color:var(--ink-2);letter-spacing:-.01em}
.dcard.attesa .dsc{font-weight:400;color:var(--line-2)}
/* Two lines, not two paragraphs: display:block and the margin only on
   the first, otherwise a gap opens between the name of the venue and
   the town that makes them look like two different pieces of
   information. They are the same one. */
.ddove{display:block;font-size:12.5px;font-weight:400;color:var(--muted);
  overflow-wrap:anywhere;line-height:1.35}
.ddove:first-of-type{margin-top:2px}
.dvuoto{padding:28px 22px;text-align:center;font-size:14px;color:var(--muted)}

/* Thin scrollbars, as in the tree of competitions.
   CAREFUL: in a list of selectors the pseudo-element attaches ONLY to
   the last one, so every selector carries its own. */
.squadre,.daybox{scrollbar-width:thin;scrollbar-color:var(--line-2) transparent}
.squadre::-webkit-scrollbar,
.daybox::-webkit-scrollbar{width:10px;height:10px}
.squadre::-webkit-scrollbar-track,
.daybox::-webkit-scrollbar-track{background:transparent}
.squadre::-webkit-scrollbar-thumb,
.daybox::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:6px;
  border:3px solid transparent;background-clip:content-box}

/* The break between home matches and away ones: a hairline and a
   little air above the first away game. Not a heading: that the two
   groups are two is already said by the emoji on every row, and this
   only shows where one ends and the other begins. */
.dcard.stacco{margin-top:14px;border-top:1px solid var(--line-2);padding-top:16px}

}

/* app/calendario.css */
@media (min-width:900px){
/* ============================================================
   THE CALENDAR: filter, month grid, day column
   It leans on everything the board already has: .shell, .panel,
   .p-head, .season, .rnav, .rlabel. In here there is only what
   belongs to this page alone.
   ============================================================ */

/* The centre holds ONE panel only. On the results page the rows are
   "auto + 1fr" because the result panel is as tall as its content and
   the list takes the rest; with that rule here the grid would stop at
   the height of the content and below it a hole half a window tall
   would be left. */
.shell.cal .centre{grid-template-rows:minmax(0,1fr)}

/* ============================================================
   THE SIDE BAR: the team filter
   ============================================================ */
/* "Tutte" and "Nessuna": two equal buttons, not one main and one for
   service. None is a legitimate state (it is how the filter is
   cleared before picking two) and a faded button would say the
   opposite. */
.ftutte{flex:none;display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:10px 12px 4px}
.ftutte button{padding:8px 4px;border-radius:8px;
  border:1px solid var(--line-2);background:var(--zebra);color:var(--brand-2);
  font-size:10.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
  transition:background .14s,border-color .14s}
.ftutte button:hover{background:var(--sunken);border-color:var(--brand)}

.squadre{flex:1;min-height:0;overflow-y:auto;padding:8px 12px 12px;
  display:flex;flex-direction:column;gap:2px}
/* 5px of padding and not 9, and it is not a cosmetic touch: the
   second line is worth fifteen pixels an item, and the eleven teams
   of 2025/26 stay inside the column only with those pixels taken back
   from here. Eleven that fit without scrolling is what this filter is
   asked for: they are all the teams of the club, and choosing them
   is the main gesture of the bar. The item stays 44px tall, which is
   above the size of a touch target. */
.sq{width:100%;display:flex;align-items:center;gap:11px;padding:5px 10px;border-radius:9px;
  text-align:left;color:var(--ink-2);transition:background .14s,color .14s}
.sq:hover{background:var(--zebra);color:var(--ink)}
/* Ticked: the same language as the chosen entry in the tree of
   competitions: a faint veil, a bar on the left, brand-coloured
   text. No solid brand fill: in the dark the white on top of it does
   not read. */
.sq.on{background-image:linear-gradient(var(--me-fill),var(--me-fill));
  box-shadow:inset 3px 0 0 var(--brand);color:var(--brand-2)}
.sq .box{flex:none;width:19px;height:19px;border-radius:5px;
  border:1.5px solid var(--line-2);background:var(--panel);display:grid;place-items:center}
.sq.on .box{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
.sq .box .ico{width:13px;height:13px}
/* TWO LINES: the name of the team and, underneath, the competitions
   it plays in. It is the same two-line item this column already uses
   in the tree of competitions on the results page (name on top,
   qualifier below in small and fainter) and not a third grammar
   invented here. The subtitle is NOT uppercase with the letter
   spacing of the season button: «3ª Divisione U16 / U16 Provinciale»
   is thirty-four characters long and in spaced uppercase not even
   half of it would fit.

   min-width:0 ON ALL THREE BOXES. The longest name is twenty-eight
   characters in a 284 column: without it the text box takes the width
   of its content as a minimum, spreads beyond the column, and the one
   that pays is the match count at the end, which is squashed or
   pushed out. With the ellipsis the count stays where it is. */
.sq .txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:0}
.sq .nm{min-width:0;font-size:14.5px;font-weight:400;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sq.on .nm{font-weight:600}
.sq .sotto{min-width:0;font-size:11.5px;font-weight:400;line-height:1.3;color:var(--faint);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sq.on .sotto{color:var(--muted)}
/* SEVERAL ENTRIES, ONE SINGLE TICK. A team can be entered more than
   once under different names (ui/iscrizioni.js) and here it is one
   single item: the checkbox lights them all together, and the count
   at the end is the sum of their matches. The item names them all
   because the name on the shirt changes from one tournament to the
   next, and whoever is looking for theirs has to find it there. */
.sq .isc{min-width:0;display:flex;flex-direction:column;gap:0}
.sq .isc + .isc{margin-top:6px}
/* A HAIRLINE BETWEEN ONE ITEM AND THE NEXT. A team can name several
   entries (ui/iscrizioni.js), so an item can be four lines tall, and
   four lines in a row with nothing in between read as four items:
   what is lost is exactly what the grouping has to say, that those
   two names are one single team and are ticked together.

   THE HAIRLINE LIVES IN THE GAP, not on the item. Drawn as a border
   of the item it becomes part of the item, and the item is a rounded
   slab: the ticked one comes out square on top and round below. This
   way the slab stays whole and the line passes through the air that
   separates them.
   Above every item except the first, otherwise one is left hanging at
   the end of the list. */
#squadre .sq{position:relative}
#squadre .sq + .sq{margin-top:9px}
#squadre .sq + .sq::before{
  content:"";position:absolute;left:0;right:0;top:-5px;height:1px;background:var(--line);
}
.sq .n{flex:none;font-size:12.5px;font-weight:400;color:var(--faint)}
.sq.on .n{color:var(--brand-2)}

/* THE SEASON OF THIS COLUMN lives in app/lato.css.
   The teams page puts it in the same place and opens it the same way,
   so the rules are written once instead of in two copies. The why of
   that choice (where the season sits in the column and which way the
   little panel opens) is written there along with the rules. */

/* ============================================================
   THE CENTRE: the heading of the days and the month grid
   ============================================================ */
.cal-dow{flex:none;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  border-bottom:1px solid var(--line);background:var(--zebra)}
.cal-dow span{padding:7px 0;text-align:center;
  font-size:10.5px;font-weight:600;letter-spacing:.1em;color:var(--faint)}
/* Saturday and Sunday on a different ground: 82% of the season is
   played there, and the grid has to say so before a single number is
   read. */
.cal-dow span:nth-child(6),.cal-dow span:nth-child(7){background:var(--sunken);color:var(--muted)}

.cal-body{flex:1;min-height:0;position:relative;display:flex}
/* SIX ROWS ALWAYS, and they are equal rows: the 42 cells arrive that
   way from core/calendario.js. A month that changes height while it
   is leafed through is the same flicker the result panel keeps out. */
.cal-grid{flex:1;min-height:0;display:grid;
  grid-template-columns:repeat(7,minmax(0,1fr));grid-template-rows:repeat(6,minmax(0,1fr))}

/* No gap between the number and the rows: the vertical space of the
   cell is counted in cal-desk.js and every pixel not declared there
   is a row that overflows. The distance is made by the line-height of
   the number. */
.cell{min-width:0;min-height:0;overflow:hidden;text-align:left;
  padding:4px 5px 5px;display:flex;flex-direction:column;
  background:var(--panel);
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  transition:background .14s}
.cell:nth-child(7n){border-right:0}
.cell:nth-child(n+36){border-bottom:0}
/* The two weekend columns. They come AFTER the base rule and BEFORE
   .fuori and .sel: they all have the same specificity (one class plus
   one pseudo-class counts as two classes) and what decides is the
   order, not the weight. */
.cell:nth-child(7n+6),.cell:nth-child(7n){background:var(--zebra)}
/* The shoulder cells: they belong to the month alongside. They stay
   clickable (they lead there) but they must not compete with the
   month being looked at. */
.cell.fuori{background:var(--sunken)}
.cell.fuori .n{color:var(--faint);opacity:.5}
.cell.fuori .righe{opacity:.42}
.cell:hover{background:var(--sunken)}
/* The day opened in the right-hand column. A faint veil and a brand
   ring: it is the same language a selection is marked with everywhere
   on the site. */
.cell.sel{background-image:linear-gradient(var(--me-fill),var(--me-fill));
  box-shadow:inset 0 0 0 2px var(--brand)}
.cell .n{flex:none;align-self:flex-start;font-size:12px;font-weight:600;
  line-height:17px;color:var(--muted)}
/* Today: the number filled with the brand colour, like the round
   chosen in the strip of the results page. */
.cell.oggi .n{background:var(--brand);color:var(--on-brand);border-radius:5px;padding:0 5px}

/* THE MEASUREMENTS OF THIS ROW ARE AGREED WITH cal-desk.js.
   How many rows fit in a cell is decided by the layout script by
   measuring the grid, and to do so it uses three numbers: 19 of row
   (17 of label plus 2 of gap, here below), 17 of day number (.cell
   .n, line-height) and 9 of padding (4 above + 5 below, on .cell).
   Changing one of them here and not there means one row too many that
   disappears under the border. */
.righe{flex:1;min-height:0;display:flex;flex-direction:column;gap:2px;overflow:hidden}

/* ============================================================
   THE LABEL SPLIT IN TWO
   ============================================================
   Two halves, and what speaks is the colour:

     left      the competition, on a ground that says WHERE it is
               played: brand veil at home (--me-fill, the same the
               site marks the Silea with), neutral veil away
               (--via-fill, which is --muted veiled). Both of them
               transparent, because underneath there can be the
               weekend cell, which has a ground of its own already.
               With the icon in front: the house, or the plane of the
               away game.
     right     a block with the result: LIGHT green won, LIGHT red
               lost, neutral drawn. The draw is not a textbook case:
               the Under 13 Primavera plays a fixed four sets. Not the
               saturated fills: forty cells of solid green and red
               make a chessboard, and the grid has to make the days
               read, not the results.

   flex:none, and it is not caution. The rows sit in a flexible
   column: without it, when the count is wrong by even half a pixel
   they all SHRINK instead of one being too many, the text stays as
   tall as it was and every row ends up on top of the next. With
   flex:none the crooked case is one row cut off by the border, which
   is seen at once and is far less bad. */
.riga{flex:none;display:flex;align-items:stretch;height:17px;min-width:0;
  border-radius:3px;overflow:hidden}
/* The left half: icon and name, and the ground that says where it is
   played. */
.riga .et{flex:1;min-width:0;display:flex;align-items:center;gap:3px;padding:0 4px}
.riga.casa .et{background:var(--me-fill);color:var(--brand-2)}
.riga.via .et{background:var(--via-fill);color:var(--muted)}
.riga .et .nm{min-width:0;font-size:10.5px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.riga .ico{flex:none;width:11px;height:11px}
/* the emoji is text: it is sized with font-size. 10px because at 11
   the house breaks out of the height of the row inside the cell. */
.riga .emo{flex:none;font-size:10px;line-height:1}
/* The right half: the result block. A fixed MINIMUM width. "17:30"
   and "3-0" have different widths, and without a minimum the two
   halves would move from one row to the next inside the same cell. */
.riga .q{flex:none;min-width:31px;display:grid;place-items:center;padding:0 4px;
  font-size:10.5px;font-weight:600;letter-spacing:-.01em}
/* Won and lost are the only two semantic colours of the house and
   they do not swap between the two themes. Here they are a PATCH and
   not coloured text (at 10px a green and a red on white are the same
   grey from a distance) but the patch is light (--up-fill /
   --down-fill) and the number on top of it is the solid green or red:
   the sign is seen from far off, and close up it does not cover the
   score. */
.riga.vinta .q{background:var(--up-fill);color:var(--up)}
.riga.persa .q{background:var(--down-fill);color:var(--down)}
.riga.pari .q{background:var(--line-2);color:var(--ink)}
/* Still to play: A QUIET GROUND, never a result colour. Green and red
   here would say a thing that has not happened yet. */
.riga.attesa .q{background:var(--sunken);color:var(--ink-2)}
.piu{flex:none;display:flex;align-items:center;height:17px;padding-left:5px;
  font-size:10.5px;font-weight:600;letter-spacing:.03em;color:var(--brand-2)}

/* The card that explains an empty grid. It is not an error: it is the
   grid saying why there is nothing, instead of looking broken. */
.cal-grid.spenta .cell .n{opacity:.4}
.cal-nota{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;
  max-width:78%;display:flex;flex-direction:column;align-items:center;gap:5px;
  text-align:center;padding:18px 26px;border-radius:12px;pointer-events:none;
  background:var(--panel);border:1px solid var(--line-2);box-shadow:var(--shadow)}
.cal-nota b{font-size:16.5px;font-weight:600;color:var(--ink)}
.cal-nota span{font-size:13.5px;font-weight:400;color:var(--muted)}
/* display:flex beats the hidden attribute, which is worth display:none
   and no more: without this line the card would stay in view for
   good. */
.cal-nota[hidden]{display:none}

/* THE MATCH CARD lives in app/gara.css.
   The homepage draws the same card in the first team's panel, and the
   markup is shared (ui/gara.js), so the sheet is too. It has to be
   loaded BEFORE this one, which corrects a few of its measurements in
   the narrow column. */

}

/* pages/calendario.css */
@media (min-width:900px){
/* THE TAIL OF THE CALENDAR PAGE SHEET.
   =============================================
   Like the tail of the results page, and for the same reason: what is
   in here is all corrections, and they ALL win by POSITION. A @media
   adds no specificity, so written before the rule it means to correct
   it loses on order and does nothing at all, with no errors and no
   warnings. This sheet is the LAST of the page before motion.css, and
   the order lives in build/build.js.

   In particular it has to come after app/griglia.css, which carries
   the two thresholds of the results board (1399 and 960): here they
   are rewritten, because the day column is not an extra like the
   table, and the month grid is not a list that grows.               */

/* ============================================================
   1399: THE DAY COLUMN DOES NOT GO AWAY
   On the results page, below 1400px, the table leaves the board and
   takes shelter behind a button: it is side information, and the
   centre needs those 400px for the box score.
   Not here. The day column IS the answer to the click on a cell, and
   the reason a day with six matches needs no popup. Without it the
   main gesture of the page has nowhere left to answer. It narrows, it
   stays.
   ============================================================ */
@media (max-width:1399px){
  .shell.cal{grid-template-columns:284px minmax(0,1fr) 348px}
  .shell.cal .aside{display:grid}
  .dcard{grid-template-columns:66px minmax(0,1fr);gap:11px;padding:9px 13px}
  .dwhen b{font-size:17.5px}
  /* «SCONFITTA» is the longest word of the strip, and the strip here
     is 66px wide: half a point less and no letterspacing keep it on a
     single line. It has to stay on one line: wrapping would raise the
     card and the six of the worst day would fall out of the column. */
  .desito{font-size:8.5px;letter-spacing:0;padding:1px 5px}
  .dsede{font-size:9px;gap:3px}
  .dsede .ico{width:12px;height:12px}
  .dteam{font-size:13.5px}
  .dsc{font-size:14px;min-width:12px}
  .drow{gap:8px}
  .dcomp,.dgio{font-size:10.5px}
  /* The cell drops from ~120 to ~99px and the competition name is the
     first to run out of room. Everything around it tightens (padding,
     the outcome block, distances) instead of cutting the icon, which
     is half the information (home or away). What is left over goes to
     the name, with an ellipsis where it does not fit. */
  .riga .et{gap:2px;padding:0 3px}
  .riga .et .nm{font-size:10px}
  .riga .q{min-width:27px;padding:0 3px;font-size:10px}
  .riga .ico{width:10px;height:10px}
}

/* ============================================================
   FLOW MODE: it has to sit at the END of the sheet
   Below 960px the board goes single column and the page really scrolls
   again. "flex:1" means "flex:1 1 0%", that is base ZERO: with
   automatic height it contributes nothing and the panels collapse
   flat. Here they go back to flex:none so they measure on content.
   The grid is the special case: with no window dictating its height it
   would crumple onto the empty rows. It gets a minimum of 576px, six
   rows of 96, the same cell height it would have on a normal screen,
   so cal-desk.js keeps counting the same three match rows inside it.
   ============================================================ */
@media (max-height:520px),(max-width:960px){
  html,body{height:auto;overflow:auto}
  /* #schermo is the container where the page mounts one layout or the
     other, and it falls into the same trap as all the rest. */
  #schermo{flex:none}
  .shell.cal{grid-template-columns:minmax(0,1fr);height:auto;overflow:visible;flex:none}
  .shell.cal .centre,.shell.cal .aside{grid-template-rows:none}
  .shell.cal .side .panel,.squadre,.daybox,.cal-body{
    flex:none;min-height:0;max-height:none;height:auto;
  }
  .squadre,.daybox{overflow:visible}
  .cal-body{display:block}
  .cal-grid{height:auto;min-height:576px}
}

/* The theme button stays in the corner even on a narrow window: first
   the links compact, then the lettering next to the crest goes. These
   are the same two rules that close the tail of the results page, and
   they cannot move into header.css: there they would apply below 900px
   too, where the mark centred in the phone header would disappear.
   They live in the board band, one copy per page, and the band is
   written by build/build.js. */
@media (max-width:1180px){
  .top-in{gap:16px}
  .nav a{padding:9px 10px;font-size:14px}
}
@media (max-width:1000px){
  .nav a{padding:8px 7px;font-size:13.5px}
  .brand .wm{display:none}
}

}

/* tel/tokens.css */
@media (max-width:899px){
/* ============================================================
   THE PHONE PALETTE: the one for showing, not another house.
   ============================================================
   These values are NOT the ones in tokens.css. The two screens tune
   their greys differently: the board keeps rules and secondary text
   stronger (--line #B7CBD9) because it has to carry large panels and
   dense tables, while the phone keeps them much fainter
   (--line #E2ECF2) because at 390px a dark rule becomes a cage.
   Tipping one onto the other is not a tidy up, it is a redesign.

   The WAY the ground is named changes too. The board says --panel and
   --ground, the phone says --paper and --surface. Different names for
   the same idea, listed in docs/DIVERGENZE.md: until the club picks
   one, both stay.

   THREE STATES, as everywhere: bare :root is the light one, the block
   inside prefers-color-scheme is for whoever has a dark system and has
   not chosen, :root[data-theme="dark"] is for whoever has chosen. A
   token declared in the light and forgotten in one of the two darks
   stays light at night, which is the classic unreadable page defect:
   tests/css.js checks this sheet too.

   The (max-width:899px) band is not written here: build/build.js adds
   it, together with the order.                                       */

:root{
  --ink:      #020909;
  --ink-2:    #40525C;
  --brand:    #0377BD;
  --on-brand: #FFFFFF;
  --accent:   #52B2D0;

  --paper:    #FFFFFF;
  --surface:  #F4F8FB;
  --sunken:   #EAF1F6;
  --line:     #E2ECF2;
  --line-2:   #D3E1EA;
  /* THE TONE OF THE DOTTED RULE. A dotted rule does not show like a
     solid one: fewer than half its pixels are lit, so at equal colour
     it comes out lighter than it is. This tone is one step stronger
     than --line-2 in both themes, which is the amount that makes a
     dotted line weigh as much as a solid --line-2 one. */
  --tratteggio: #BACDDA;
  /* DARK ENOUGH TO READ: --faint stays above 4.5:1 and --muted above
     7:1, the two AA thresholds for text. A grey under 3:1 on light
     paper is not "readable with effort", it is not there at all, and
     the phone is the screen that needs more contrast and not less:
     outdoors, with the display dimming itself. */
  --muted:    #4C5E6A;
  --faint:    #5F7280;

  /* Header and drawer follow the theme like everything else. The rule
     under the header is lighter than on the board: there it separates
     two panels, here it only separates the top from the content. */
  --head:      #FFFFFF;
  --head-fg:   #0B1A22;
  --head-dim:  #54697A;
  --head-line: #DCE8F0;
  --menu-line: #E2ECF2;

  --up:       #12885A;
  --down:     #C6412F;
  /* The LIGHT green and red, for the win/loss label in the agenda
     card. Same idea as the board (styles/tokens.css), and in the light
     theme the same values too, because the starting green and red are
     the same here. In the dark they are not: there the phone lightens
     --up and --down and the patch under them has to follow. Solid and
     not veiled, since a veil leans on what is under it and here there
     are two different grounds (the paper and the day strip).
     Measured contrast of the text on top: 3,4:1 green and 3,7:1 red in
     the light, 5,4:1 and 4,7:1 in the dark, better in the dark because
     there the phone lightens --up and --down.
     CAREFUL: tests/theme.js resolves the tokens from the BOARD
     palette, so nothing measures these four lines on its own. They are
     computed by hand, and have to be redone by hand if anyone touches
     --up or --down above. */
  --up-fill:   #C9E7D8;
  --down-fill: #F6D6D0;

  --silea-fill: rgba(164,210,230,.16);
  --set-win:    rgba(164,210,230,.55);
  --bird-op:  .40;
  /* MINIMUM height of the Silea card: the same with a result, with a
     countdown and with a bye. Left to itself the card comes out ~206px
     with a result, ~187px waiting and ~150px on a bye, so changing
     matchday makes it dance and the whole list below with it. On the
     board the same number is 270px, because the five column box score
     fits in there as well. */
  --hero-h:   212px;
  --scrim:    rgba(2,9,9,.45);
  /* The ground the app rests on. It never shows, since the screen
     covers all of it, but if one day something did not reach the
     bottom, what lies under is this and not the white of the
     browser. */
  --stage:    #DCE7EE;
}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ink:      #EFF6F9;
    --ink-2:    #BCCAD2;
    --brand:    #52B2D0;
    --on-brand: #03151C;
    --accent:   #52B2D0;

    --paper:    #0B1317;
    --surface:  #050C0F;
    --sunken:   #101B21;
    --line:     #182831;
    --line-2:   #22343E;
    --tratteggio: #3E525F;
    --muted:    #7F949F;
    --faint:    #5D717C;

    --head:      #020909;
    --head-fg:   #FFFFFF;
    --head-dim:  #7E939F;
    --head-line: #122029;
    --menu-line: #16232A;

    /* In the dark the green and red of the board would disappear into
       the ground: here they gain brightness. It is the only point
       where the two layouts disagree even on semantic colours. */
    --up:       #2AAE74;
    --down:     #E0604D;
    /* In the dark "light" means dark: the patch has to stay under the
       green and red lightened above, not over them. */
    --up-fill:   #0F2A21;
    --down-fill: #2E1A15;

    --silea-fill: rgba(82,178,208,.10);
    --set-win:    rgba(82,178,208,.20);
    --bird-op:  .10;
    --scrim:    rgba(0,0,0,.62);
    --stage:    #04090C;
  }
}

:root[data-theme="dark"]{
  --ink:      #EFF6F9;
  --ink-2:    #BCCAD2;
  --brand:    #52B2D0;
  --on-brand: #03151C;
  --accent:   #52B2D0;

  --paper:    #0B1317;
  --surface:  #050C0F;
  --sunken:   #101B21;
  --line:     #182831;
  --line-2:   #22343E;
  --tratteggio: #3E525F;
  --muted:    #7F949F;
  --faint:    #5D717C;

  --head:      #020909;
  --head-fg:   #FFFFFF;
  --head-dim:  #7E939F;
  --head-line: #122029;
  --menu-line: #16232A;

  --up:       #2AAE74;
  --down:     #E0604D;
  --up-fill:   #0F2A21;
  --down-fill: #2E1A15;

  --silea-fill: rgba(82,178,208,.10);
  --set-win:    rgba(82,178,208,.20);
  --bird-op:  .10;
  --scrim:    rgba(0,0,0,.62);
  --stage:    #04090C;
}

}

/* tel/base.css */
@media (max-width:899px){
/* ============================================================
   THE GROUND OF THE PHONE SCREEN
   ============================================================
   There is no frame around the screen: the ground and the clipping are
   shared between the body of the page and #schermo.

   NOTHING SCROLLS AT PAGE LEVEL. Only the middle strip scrolls, inside
   the app, and that is what makes the screen feel like an application
   and not a document. With a scrolling body the sheets rising from the
   bottom would drag the page along under them, and the sponsor bar at
   the foot would slide away.

   This sheet also redoes the reset (*, button, :focus-visible):
   app/base.css does it for the board and is bounded above 900px, so it
   does not reach down here. The four lines are not identical to the
   board ones: the type is 16px at line height 1,4, not 17 and 1,5. */

*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
html,body{height:100%;overflow:hidden}

body{
  display:flex;flex-direction:column;
  background:var(--stage);
  color:var(--ink);
  font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:16px;
  line-height:1.4;
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.u-num{font-variant-numeric:tabular-nums}
.lbl{
  font-size:10px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--muted);
}

/* #schermo takes whatever is left under the header and passes it on
   unchanged to the app. overflow:hidden: a panel that overflows
   overflows inside its own strip and does not lengthen the page. The
   sheets rising from the bottom are untouched, being fixed, so the
   clipping of an ancestor does not reach them. */
#schermo{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}

.app{flex:1;min-height:0;display:flex;flex-direction:column;background:var(--surface)}

.scroll{
  flex:1;min-height:0;
  overflow-y:auto;overflow-x:hidden;
  overscroll-behavior-y:contain;
  -webkit-overflow-scrolling:touch;
  scroll-behavior:smooth;
}
/* One pixel tall and at the top of the scrolling strip: when it leaves
   the view, the header recomposes. One pixel and not zero, because an
   element with no height never intersects anything. */
#sentinel{height:1px}

/* The scrollbar, thinner than on the board: here the screen is 390 and
   ten pixels are a fortieth of the usable width. The rest (colours,
   radius, transparent frame) comes from styles/scorrimento.css and is
   not repeated. */
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{border-radius:5px;border-width:2px}

}

/* tel/testata.css */
@media (max-width:899px){
/* ============================================================
   THE HEADER, ON THE PHONE: corrections and the name that recomposes
   ============================================================
   The header is drawn by header.css, which belongs to every page, and
   below 900px it already draws it nearly as the phone wants: hammer on
   the left, brand in the middle, theme on the right, three columns
   44 · 1fr · 44. Four differences are left, and none of them is taste.

   1. --testa TALL IN ALL, hairline included, and with no padding.
      header.css puts min-height on the CONTENT and 4px of side
      padding: the hairline adds to it (one pixel across the width that
      pushes everything down) and the two icons slide 4px towards the
      middle. With box-sizing:border-box the height on the band takes
      in the hairline and the content stays a pixel lower. The
      min-height goes off with it, or it wins.
   2. NOT sticky. The page does not scroll here, only the middle strip
      does: a sticky would have nothing to follow.
   3. THE WEIGHTS. The shared chrome works on the board scale, where
      the highest declared is 600; the phone writes brand and watermark
      at 800. It is one of the catalogued divergences
      (docs/DIVERGENZE.md): it is not unified, it is reproduced.
   4. The theme button carries the 20px icon like the other two, not
      the 19 of the board. Half a pixel a side, but it is half a pixel
      in the top right corner of every screen.

   The colour is declared on .top so the children inherit it: the
   competition name below sets none of its own, and without this line
   it would inherit --ink, which on the light theme is darker than
   --head-fg.                                                         */
.top{position:static;flex:none;height:var(--testa);color:var(--head-fg);overflow:hidden}
.top-in{height:100%;min-height:0;padding:0;position:relative}
.tema svg{width:20px;height:20px}

/* HALF A PIXEL, AND IT SHOWS.
   THE LINK IS AS BIG AS THE CREST, not as the column. .brand leads to
   the home page and is the middle cell of a 44 · 1fr · 44 grid: as a
   grid item it stretches across the whole middle column and takes the
   full height of the band, so a finger landing anywhere at the top (to
   scroll, or by mistake) leaves the page. A brand is tapped where the
   brand is seen: justify-self tightens it onto the content and the
   height drops to that of the crest. That leaves 76 by 56 pixels of
   target, well over the 44 a tappable thing has to measure.
   The two measurements are EVEN and so is the band: the brand centres
   on a whole pixel and its edges keep their colour. With odd
   measurements it would redraw half a pixel higher, and that is the
   difference the test finds first. */
.brand{height:var(--stemma);justify-self:center}

/* ------------------------------------------------------------------
   THE HEADER THAT RECOMPOSES
   Scrolling, the competition bar leaves the stage and its name
   recomposes in the middle of the header: whoever looks never loses
   sight of what is being read, and the matchday stays stuck below.

   The middle column here is .brand, which comes from the shared
   chrome: wrapping it would change it for the sponsor page too, for a
   piece one page needs. So the second layer overlaps instead, and
   left/right at 44px are exactly the two edges of the middle column.

   The class "collapsed" sits on the BODY: the header is outside
   #schermo, and lighting both layers with a single class takes a
   common ancestor.
   ------------------------------------------------------------------ */
.hdr-comp{
  /* The full height and not "top to bottom": it is the same box, and
     it overruns the content of the band by a pixel. With bottom:0 the
     box would be a pixel shorter and the name would centre half a
     pixel above the brand it replaces. */
  position:absolute;left:44px;right:44px;top:0;height:var(--testa);
  display:flex;align-items:center;justify-content:center;gap:6px;
  opacity:0;transform:translateY(8px);pointer-events:none;
  font-size:13.5px;font-weight:600;letter-spacing:-.005em;
  max-width:100%;padding:0 4px;
  transition:opacity .22s ease, transform .22s ease;
}
/* NEVER wrapping and never wider than the column: the FIPAV names
   carry the sponsor inside, and "3ª Divisione U16 · 25/26" at 13,5px
   barely fits. */
.hdr-comp .txt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hdr-comp .chev{color:var(--head-dim);font-size:11px}
.brand{transition:opacity .22s ease, transform .22s ease}
body.collapsed .brand{opacity:0;transform:translateY(-8px)}
body.collapsed .hdr-comp{opacity:1;transform:none;pointer-events:auto}

}

/* tel/barre.css */
@media (max-width:899px){
/* ============================================================
   THE TWO BARS ABOVE THE CONTENT
   ============================================================
   The first says WHAT is being looked at (competition and season) and
   scrolls away, because once read it is done. The second says WHERE
   inside that competition (the matchday, or the table caption) and
   stays stuck at the top, because that one is always needed.        */

/* ---- competition bar: scrolls away ---- */
.compbar{
  background:var(--paper);
  border-bottom:1px solid var(--line);
  padding:12px 12px 12px 14px;
  display:flex;align-items:center;gap:10px;
}
.comp{
  flex:1;min-width:0;
  display:flex;align-items:center;gap:11px;text-align:left;
}
.badge{
  flex:none;width:38px;height:38px;border-radius:10px;
  background:var(--ink);color:var(--paper);
  display:grid;place-items:center;
  font-size:15px;font-weight:800;letter-spacing:-.03em;
}
/* THE COMPETITION TAG, in the brand face: the reason at length is in
   app/lato.css, where the same tag appears in the board tree.
   .badge alone is not enough: the teams page uses the same class for
   the tag of a TEAM, and that sheet loads alongside this one. Only the
   competition is tinted here, in the bar at the top and in the sheet
   that a tap opens.
   Letter spacing is zero: this face is narrow already. Weight is 400
   because it has a single cut. */
.compbar .badge,
#compList .opt .badge{font-family:var(--titoli);font-weight:400;letter-spacing:0}

.comp-txt{min-width:0;display:flex;flex-direction:column;gap:1px}
.comp-txt .t{
  font-size:16px;font-weight:700;letter-spacing:-.015em;
  display:flex;align-items:center;gap:5px;
}
.comp-txt .t .chev{color:var(--faint);font-size:11px;flex:none}
.comp-txt .s{
  font-size:11.5px;color:var(--muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* The season is a pill, not a full width button like in the board
   sidebar: here it shares the line with the competition name, which is
   the important part, so it takes as little room as it can. */
.season{
  flex:none;
  display:flex;align-items:center;gap:5px;
  padding:7px 10px;border-radius:8px;
  background:var(--sunken);
  font-size:13px;font-weight:700;letter-spacing:.01em;
}
.season .chev{color:var(--faint);font-size:10px}

/* ---- sub bar: stays stuck ---- */
.subbar{
  position:sticky;top:0;z-index:20;
  background:var(--paper);
  border-bottom:1px solid var(--line);
  height:52px;
}
.rounds{height:100%;display:grid;grid-template-columns:44px 1fr auto 44px;align-items:center}
.rnav{
  height:44px;display:grid;place-items:center;color:var(--ink);
  transition:opacity .15s;
}
.rnav[disabled]{opacity:.22;cursor:default}
.rnav svg{width:16px;height:16px}
.rmid{text-align:center;line-height:1.15}
.rmid .n{font-size:13px;font-weight:800;letter-spacing:.09em}
.rmid .d{font-size:11px;color:var(--muted);margin-top:1px}
/* table sub header: caption on the left, options on the right */
.tblbar{height:100%;display:flex;align-items:center;justify-content:space-between;
  gap:10px;padding:0 12px 0 14px;position:relative}

/* switch inside the cup run: matches or group.
   It sits in the bar, next to the caption: compact. */
.pswitch{flex:none;display:flex;gap:4px;background:var(--sunken);
  border-radius:9px;padding:3px}
.pswitch button{
  padding:6px 12px;border-radius:7px;background:transparent;color:var(--muted);
  font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
}
.pswitch button.on{background:var(--brand);color:var(--on-brand)}

/* ---- cup run ----
   The markup comes from src/scripts/ui/percorso.js, the same for both
   layouts. Here are the phone measurements: the board ones, a couple
   of points smaller. */
.perc{padding:4px 0 10px}
.perc .tappa{padding:12px 14px;border-bottom:1px solid var(--line)}
.perc .tappa:last-child{border-bottom:0}
.perc .tappa.qui{background:var(--silea-fill);box-shadow:inset 3px 0 0 var(--brand)}
.perc .cima{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin-bottom:7px}
.perc .nome{font-size:10.5px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--ink-2)}
/* Two team lines per match, home on top, one score per line: the same
   shape as the Silea card. The markup is the board one
   (ui/percorso.js), a couple of points smaller here. */
.perc .gara{display:grid;grid-template-columns:14px minmax(0,1fr) auto;align-items:center;
  gap:8px;padding:4px 0;font-size:13px;color:var(--muted)}
.perc .gara .sg{font-weight:700;text-align:center}
.perc .gara.vinta .sg{color:var(--up)}
.perc .gara.persa .sg{color:var(--down)}
.perc .gara .sq{min-width:0;display:flex;flex-direction:column;gap:1px}
.perc .gara .ln{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}
.perc .gara .ln.noi{color:var(--brand);font-weight:700}
.perc .gara .ris{display:flex;flex-direction:column;gap:1px;text-align:right;
  font-variant-numeric:tabular-nums}
.perc .gara .ris b{font-weight:700;color:var(--ink);line-height:1.3}
/* THE DATE IN PLACE OF THE SCORE. It is wider than a set count and
   must neither wrap nor push the names. Plain weight and tone, because
   a score is a result while a date is service information. Tabular
   figures, so that four dates one under the other read as a column. */
.perc .gara .ris .na{font-weight:500;font-size:11px;color:var(--muted);white-space:nowrap}
/* A HAIRLINE BETWEEN ONE MATCH AND THE NEXT in the same group. A cup
   group holds four matches, each two lines tall: with nothing in
   between, eight lines of names read as a single list and only the
   hourglass says which two go together. The hairline is as light as
   the ones in the site lists. The LAST match has none: the stage
   border, or the outcome line, already closes it. */
.perc .gara + .gara{border-top:1px solid var(--line);padding-top:7px;margin-top:7px}
.perc .esito{margin-top:6px;font-size:12px;color:var(--muted)}
.perc .esito b{font-weight:700;color:var(--ink-2)}
.perc .esito.vinto b{color:var(--up)}

.tblcap{
  display:flex;align-items:center;
  font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);
}

.perc .gara .sg{font-size:12px}

}

/* tel/eroe.css */
@media (max-width:899px){
/* ============================================================
   THE SILEA CARD
   ============================================================
   It is the first thing seen and the only one that opens: the other
   matches of the round show the result and nothing more. Three states
   (played, waiting, rest) and a single height.                       */
.hero{
  background:var(--paper);
  border:1px solid var(--line);
  border-left:3px solid var(--accent);
  border-radius:14px;
  overflow:hidden;position:relative;
  background-image:linear-gradient(180deg,var(--silea-fill),transparent 70%);
  width:100%;text-align:left;
  /* ONE HEIGHT for the three states. Left alone the card runs about
     206px with the result, 187 waiting and 150 at rest: changing round
     it wobbles, and the whole list under it with it. The minimum evens
     them out and the name band takes up the slack. */
  min-height:var(--hero-h);
  display:flex;flex-direction:column;
}

/* ------------------------------------------------------------------
   THE SPARROW. On the phone it stays still, mirrored, hooked to the
   right edge of the card: part of it stays outside and the card cuts
   it, as if it were peeking in from the margin. No animation: on a
   small screen a continuous movement only distracts, which is why this
   is a figure of its own and not .bird from sparrow.css.
   ------------------------------------------------------------------ */
.hero-birds{position:absolute;inset:0;overflow:hidden;pointer-events:none;border-radius:inherit}
.hero-bird{
  position:absolute;top:50%;right:0;
  height:170%;width:auto;aspect-ratio:3/2;
  background:url("/light_sparrow.04c82cab.svg") center/contain no-repeat;
  /* scaleX(-1) mirrors it, the 34% pushes it past the right edge */
  transform:translate(34%,-50%) scaleX(-1);
  opacity:var(--bird-op);
}
.hero-content{position:relative;flex:1;display:flex;flex-direction:column}
.hero-top{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:11px 14px 0;
}
/* THE WHEN AND WHERE LINE, READABLE. Eleven pixels and the text grey,
   a step darker than the muted one: it stays an outline around the
   score, but an outline that can be read. */
.hero-meta{
  font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.chip{
  flex:none;padding:4px 9px;border-radius:6px;
  font-size:10.5px;font-weight:900;letter-spacing:.09em;
  background:var(--brand);color:var(--on-brand);
}
.chip.ghost{background:var(--sunken);color:var(--muted)}
/* Takes the slack when the card is taller than its content, so the
   band at the foot stays glued to the edge and the block stays
   centred. */
.hero-rows{flex:1;justify-content:center;
  padding:12px 14px 4px;display:flex;flex-direction:column;gap:9px}
.hrow{display:flex;align-items:center;gap:10px}
/* NAMES TRUNCATE, THEY NEVER WRAP. A wrapped club name makes its card
   or row taller than its neighbours, and on a phone that is the
   difference between a list you can run your eye down and one you have
   to read. The full name is always a tap away. */
.hrow .nm{
  flex:1;min-width:0;font-size:16px;letter-spacing:-.015em;
  line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.hrow .sc{
  flex:none;font-size:26px;font-weight:800;letter-spacing:-.03em;
  min-width:22px;text-align:right;
}
.hrow.silea .nm{
  font-weight:700;text-transform:uppercase;letter-spacing:.005em;
}
.hero-sets{
  padding:2px 14px 12px;
  display:flex;flex-wrap:wrap;gap:5px;
  justify-content:flex-end;   /* right aligned, like the scores above */
}
/* set won by Silea: pale blue ground and the team colour for text */
.st.won{background:var(--set-win);color:var(--brand);font-weight:700}
.st{
  font-size:11px;font-weight:600;letter-spacing:.01em;
  padding:3px 6px;border-radius:5px;
  background:var(--sunken);color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.hero-foot{
  border-top:1px solid var(--line);
  padding:10px 14px;
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-size:11px;font-weight:700;letter-spacing:.055em;text-transform:uppercase;
  color:var(--brand);
}
.hero-foot .arr{color:var(--faint)}
.hero-kick{
  padding:14px;display:flex;align-items:center;justify-content:center;
  flex-direction:column;gap:2px;
}
.hero-kick .sub{font-size:11.5px;color:var(--muted)}
/* THE COUNTDOWN, the same four boxes as the wide card. Four boxes
   with a number in each are read before the text around them, which is
   the point of putting them there.
   The proportions are the phone ones, not the desk ones: 52px wide
   instead of 60, so four of them plus their gaps fit inside 358px with
   room to spare and the card does not grow. */
.hero-kick .cd{display:flex;gap:6px;margin-top:8px}
/* FOUR BOXES OF ONE WIDTH. The minimum has to clear the widest label,
   GIORNI, or that box alone grows and the row reads as three boxes and
   a mistake. The desk sheet gets away with 60px because its label is
   smaller relative to it. The phone needs its own number, measured
   against its own type size. */
.hero-kick .cd div{background:var(--cd-fill);border:1px solid var(--cd-line);
  border-radius:8px;padding:3px 6px;min-width:52px;text-align:center}
.hero-kick .cd b{display:block;font-size:15px;font-weight:800;letter-spacing:-.03em;
  line-height:1.15;font-variant-numeric:tabular-nums;color:var(--ink)}
.hero-kick .cd span{display:block;font-size:8px;font-weight:600;letter-spacing:.09em;
  line-height:1.2;text-transform:uppercase;color:var(--faint)}

/* ---- crests ----
   Three sizes only: normal in the card, small in the lists and the
   table, large on a rest round. */
.cr{
  flex:none;width:24px;height:24px;border-radius:50%;
  display:grid;place-items:center;
  font-size:8.5px;font-weight:800;letter-spacing:-.02em;
  background:var(--sunken);color:var(--muted);
}
.cr.vs{background:linear-gradient(145deg,var(--accent),var(--brand));color:var(--on-brand)}
.cr.sm{width:18px;height:18px;font-size:7px}
/* The sparrow in place of the circle and the name in the brand face,
   inside the card only: the reason at length is in app/tabellino.css.
   Here the circle has no border, so there is nothing to switch off. */
.cr.vs{background:var(--passero) center/contain no-repeat;color:transparent}


/* ---- rest round ----
   With an odd number of teams Silea sits some rounds out, and the card
   has to stay the same height: it is the same panel, with three
   centred lines inside. */
.hero.riposo{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:9px;padding:26px 16px;text-align:center;border-left-color:var(--line)}
/* The sparrow is absolutely positioned, and in paint order POSITIONED
   elements sit above those in normal flow whatever the markup order:
   without this line the crest and the text end up under the sparrow.
   The other two cards do not have the problem because their content
   sits inside .hero-content, which is relative; here it is a direct
   child of the card. */
.hero.riposo > :not(.hero-birds){position:relative}
.hero.riposo .cr{width:40px;height:40px;font-size:12px}
.hero.riposo b{font-size:16px;font-weight:700;letter-spacing:-.01em}
.hero.riposo .sub{font-size:12.5px;color:var(--muted)}

/* ---- the dividing rule ---- */
.rule{
  display:flex;align-items:center;gap:10px;
  margin:22px 2px 10px;
}
.rule::before,.rule::after{content:"";flex:1;height:1px;background:var(--line)}
.rule span{
  font-size:9.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint);
}

}

/* tel/partite.css */
@media (max-width:899px){
/* ============================================================
   THE OTHER MATCHES OF THE ROUND
   ============================================================
   Compact rows: date and time on the left in a narrow column, the two
   teams on the right, the set scores below. They do not open, they
   show the result and nothing more, and Silea never appears in here,
   because it is in the card above.                                   */
.rows{
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:14px;
  overflow:hidden;
}
.row{
  /* 70 and not 58: "25/04/2026" has to fit on one line */
  display:grid;grid-template-columns:70px 1fr;
  width:100%;text-align:left;
  border-top:1px solid var(--line);
}
.row:first-child{border-top:0}
.rail{
  border-right:1px solid var(--line);
  padding:11px 0;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:1px;
  font-variant-numeric:tabular-nums;
}
.rail .d{font-size:10px;font-weight:700;letter-spacing:.02em;color:var(--muted);
  font-variant-numeric:tabular-nums;white-space:nowrap}
.rail .t{font-size:12.5px;font-weight:600;color:var(--ink)}
.rail .f{font-size:9.5px;font-weight:800;letter-spacing:.07em;color:var(--faint)}
.body{padding:10px 12px 10px 11px;min-width:0}
.trow{display:flex;align-items:center;gap:8px}
.trow + .trow{margin-top:5px}
.trow .nm{
  flex:1;min-width:0;font-size:14px;
  line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.trow .sc{
  flex:none;font-size:16px;font-weight:800;letter-spacing:-.02em;
  min-width:14px;text-align:right;font-variant-numeric:tabular-nums;
}
.sets{
  margin-top:7px;font-size:10.5px;color:var(--faint);
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* --- outcome: winner / loser ----------------------------------------
   Declared AFTER .hrow and .trow on purpose: both bases carry the same
   specificity (0,2,0), so only the order decides. If .trow .sc came
   later it would put weight 800 back on both scores and leave the
   difference to colour alone. Here the gap is a step of weight plus a
   step of colour, and it holds the same in both formats.             */
.win .nm{font-weight:700;color:var(--ink)}
.win .sc{font-weight:700;color:var(--ink)}
.lose .nm{font-weight:500;color:var(--ink-2)}
.lose .sc{font-weight:500;color:var(--ink-2)}

/* --- Silea panel: the accent follows IDENTITY, not the result -------
   Winner and loser do not apply here. The Silea row is always the one
   picked out, in team colour, even in a lost match: the colour says
   "this is us", the result is said by the numbers.
   Specificity 0,2,1 beats .win/.lose (0,2,0) without touching them, so
   in the compact rows (where Silea never appears) the logic by outcome
   stays valid.                                                      */
.hrow.silea .nm{color:var(--brand)}
.hrow.silea .sc{color:var(--brand);font-weight:800}
/* THE SCORE TAKES THE TEAM COLOUR, like the name beside it. It is the
   same rule the hero row above follows and the same one the board
   follows in .mres .me: our number is ours, whether we won it or lost
   it. Written after .win/.lose on purpose, because those paint by
   outcome and identity comes first. */
.trow.silea .nm{color:var(--brand);font-weight:700}
.trow.silea .sc{color:var(--brand);font-weight:800}
.hrow.opp .nm{color:var(--ink-2);font-weight:500}
.hrow.opp .sc{color:var(--ink-2);font-weight:500}

}

/* tel/piede.css */
@media (max-width:899px){
/* ============================================================
   AT THE BOTTOM: SWITCH AND SPONSOR BAR
   ============================================================
   The Results/Table switch sits at the bottom and not at the top
   because the thumb reaches the bottom. For the same reason it is not
   in the drawer: it is the most frequent gesture of the screen.     */
.tabs{
  flex:none;
  background:var(--paper);
  border-top:1px solid var(--line);
  padding:7px 12px;
}
.seg{
  display:grid;grid-template-columns:1fr 1fr;
  background:var(--sunken);border-radius:10px;padding:3px;
  position:relative;
}
/* The pill slides, the two words stay still: it reads as a switch and
   not as two buttons. It sits below (implicit z-index) with the
   buttons above, or it would cover the words. */
.seg .thumb{
  position:absolute;top:3px;left:3px;
  width:calc(50% - 3px);height:calc(100% - 6px);
  background:var(--paper);border-radius:8px;
  border:1px solid var(--line);
  transition:transform .22s cubic-bezier(.4,0,.2,1);
}
.seg button{
  position:relative;z-index:1;
  padding:9px 0;border-radius:8px;
  font-size:12.5px;font-weight:700;letter-spacing:.02em;
  color:var(--muted);transition:color .18s;
}
.seg button.on{color:var(--ink)}
.seg[data-tab="table"] .thumb{transform:translateX(100%)}

/* The sponsor bar: three plates, two below 340px. The layout decides
   the number (shells/phone.js) and writes the columns only when that
   number really changes: rewriting them at every jolt of the window
   would restart the rotation from the beginning. */
.sponsors{
  flex:none;
  background:var(--paper);
  border-top:1px solid var(--line);
  padding:9px 10px calc(9px + env(safe-area-inset-bottom,0px));
  display:grid;gap:8px;
  --h:34px;                /* usable height of the mark inside the plate */
}
/* Plate white at night too: the mark files have a white ground baked
   in (none of them has an alpha channel), and on a dark ground they
   would be fifteen white rectangles. Fixed white means the ground of
   the file disappears into the plate. */
.slot{
  height:40px;border-radius:7px;
  background:#fff;border:1px solid var(--line);
  display:grid;place-items:center;
  overflow:hidden;padding:0 7px;
}
/* --k evens out the AREA between marks of different proportions (here
   from 0.91 to 4.10): without it a long wordmark as tall as a square
   mark would weigh three times as much. object-fit rescales the marks
   wider than the plate, so the proportion never distorts. */
.slot img{
  display:block;width:100%;height:calc(var(--h) * var(--k,1));
  object-fit:contain;object-position:center;
  transition:opacity .42s ease;
}
.slot img.out{opacity:0}
.slot img.scuro{border-radius:3px}

}

/* tel/fogli.css */
@media (max-width:899px){
/* ============================================================
   THE SHEETS THAT RISE FROM THE BOTTOM
   ============================================================
   Competition, season and match detail are not pages: they are sheets
   that cover the screen for the length of a choice and then go. They
   rise from the bottom because that is where the thumb comes from, and
   they close by dragging down, by tapping the veil, or with Esc.

   FIXED POSITION, not absolute. Anchored to #schermo they would start
   BELOW the header and the veil would leave it uncovered. Fixed, they
   measure against the window, which is the box they need.            */
.scrim{
  position:fixed;inset:0;z-index:60;
  background:var(--scrim);
  opacity:0;pointer-events:none;transition:opacity .22s;
}
.scrim.on{opacity:1;pointer-events:auto}

.sheet{
  position:fixed;left:0;right:0;bottom:0;z-index:70;
  background:var(--paper);
  border-radius:18px 18px 0 0;
  transform:translateY(101%);
  transition:transform .28s cubic-bezier(.32,.72,0,1);
  max-height:82%;display:flex;flex-direction:column;
  padding-bottom:env(safe-area-inset-bottom,0px);
}
.sheet.on{transform:none}
/* drag zones: the browser must not read the gesture itself */
.grab,.md-fixed{touch-action:none}
.grab{padding:9px 0 4px;display:grid;place-items:center;flex:none}
.grab i{width:34px;height:4px;border-radius:2px;background:var(--line-2);display:block}
/* THE TITLE APART FROM THE HANDLE. A grip to pull and the name of
   what is on screen are two unrelated things, and stuck together they
   read as one piece. Twelve above and twelve below: the title floats
   in its own space and the bar goes back to being a grip. */
.sheet h3{
  flex:none;padding:12px 18px 12px;
  font-size:16px;font-weight:700;letter-spacing:-.015em;
}
/* position:relative for a sure reference: the measurements of the
   items are read against this box, not against some ancestor */
.sheet-body{position:relative;flex:1;min-height:0;overflow-y:auto;padding:0 10px 14px;overscroll-behavior:contain}
/* FIXED HEIGHT, not "as much as it takes".
   The match sheet is set on the tallest of the three tabs, the five
   set chart: 120 + 122 + 48 + 234 = 538. Changing tab (chart, photos,
   report) the sheet neither shortens nor wobbles.
   The competition one sits at 82% for the same reason: changing
   section the list gets shorter or longer, and with automatic height
   it wobbles under the fingers while choosing. */
#matchSheet{height:min(88%,538px)}
#compSheet{height:82%}
/* score, box score and tabs stay put at the top, only the panel below
   scrolls: the gallery does not carry the result away */
.md-fixed{flex:none;border-bottom:1px solid var(--line)}
.md-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding-bottom:calc(8px + env(safe-area-inset-bottom,0px))}
.md-scroll::-webkit-scrollbar{width:8px}
.md-scroll::-webkit-scrollbar-track{background:transparent}
.md-scroll::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:5px;
  border:2px solid transparent;background-clip:content-box}
/* The scrollbars are in styles/scorrimento.css, and the phone size in
   tel/base.css. */
/* Three tabs at the top of the "Scegli la competizione" sheet. 1fr
   columns: the same width for all three, whatever the length of the
   word. minmax(0,1fr) or the content dictates the minimum. */
.ttabs{
  flex:none;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:6px;padding:4px 14px 10px;
}
.ttabs button{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;
  padding:9px 4px;border-radius:10px;min-width:0;
  border:1px solid transparent;background:var(--sunken);
  font-size:9.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);
}
.ttabs button.on{background:var(--silea-fill);border-color:var(--brand);color:var(--brand)}
/* section with no data: switched off */
.ttabs button[disabled]{background:transparent;border-color:transparent;
  color:var(--faint);opacity:.45}
.ttabs svg{width:17px;height:17px;flex:none}
.ttabs .lbl{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.grp{padding:12px 8px 5px;font-size:9.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}
.opt{
  width:100%;display:flex;align-items:center;gap:11px;
  padding:11px 8px;border-radius:10px;text-align:left;
}
.opt:active{background:var(--sunken)}
.opt .badge{width:32px;height:32px;border-radius:8px;font-size:13px}
.opt .txt{flex:1;min-width:0}
.opt .txt b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.opt .txt small{display:block;font-size:11.5px;color:var(--muted);margin-top:1px}
/* WHO PLAYS IT, between the tournament and the group: the same ladder
   as the board sidebar (app/lato.css .tree .txt .chi). "U16
   Provinciale / Girone C" does not say whether it is LagoVerde or MGI
   Tools, and those are two teams with two tables.
   Never wrapping: at 390px a twenty-eight character federation name
   would push the tick off to the right. */
.opt .txt .chi{display:block;font-size:12px;font-weight:500;color:var(--ink-2);
  margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.opt .tick{color:var(--brand);opacity:0;flex:none}
.opt.sel .tick{opacity:1}
/* More than one entry inside an item (ui/iscrizioni.js): every name
   with its leagues below, and a gap between the pairs. */
.opt .isc + .isc{display:block;margin-top:7px}
.opt.sel .txt b{font-weight:700}
.opt[disabled]{opacity:.42;cursor:default}
.opt[disabled] .badge{background:var(--sunken);color:var(--faint)}

/* season sheet: compact pills */
.pills{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:4px 8px 8px}
.pill{
  padding:14px 0;border-radius:10px;text-align:center;
  background:var(--sunken);
  font-size:14px;font-weight:700;letter-spacing:.01em;
}
.pill.sel{background:var(--ink);color:var(--paper)}
.pill[disabled]{opacity:.4;cursor:default}

/* match detail sheet */
/* APART FROM THE HANDLE like the titles of the other sheets. This one
   has no <h3>, its first line is the date, so the spacing of .sheet h3
   does not reach it and is written here. */
.md-head{padding:12px 18px 14px;display:flex;flex-direction:column;gap:12px}
/* it goes INSIDE .md-when: as a sibling it would take the 12px gap of
   .md-head and the 18px inset a second time. Inherited uppercase and
   bold are cancelled here. */
.md-dove{display:block;margin-top:6px;font-size:14.5px;font-weight:500;
  letter-spacing:0;text-transform:none;color:var(--ink-2);line-height:1.45}
/* WHEN AND WHERE ARE THE ANSWER, not a caption. They are the two
   things the card is opened to find out: what time on Saturday, and
   which gym. Larger size and the text colour, not the label dress the
   rest of the site gives to labels. */
.md-when{font-size:13.5px;font-weight:700;letter-spacing:.01em;
  text-transform:none;color:var(--ink)}
.md-rows{display:flex;flex-direction:column;gap:10px}
.md-note{padding:10px 18px 14px;font-size:12.5px;color:var(--muted);line-height:1.5}

/* THE DIRECTIONS BUTTON. As wide as the text and not as the sheet: it
   is an action, and an action is tapped where it is written. Forty
   four tall, like everything touched with a thumb. */
.md-mappa{display:inline-flex;align-items:center;gap:9px;
  margin:0 18px 18px;min-height:44px;padding:0 16px;box-sizing:border-box;
  border:1px solid var(--line);border-radius:11px;background:var(--velo);
  color:var(--brand);text-decoration:none;
  font-size:14.5px;font-weight:600}
.md-mappa svg{width:18px;height:18px;flex:none}
.md-mappa:active{background:var(--zebra)}

/* --- match tabs: chart · photos · report --------------------------- */
.mtabs{display:flex;gap:4px;padding:4px;margin:4px 14px 10px;
  background:var(--sunken);border-radius:10px}
.mtabs button{flex:1;padding:9px 0;border-radius:8px;font-size:11.5px;font-weight:700;
  letter-spacing:.04em;color:var(--muted);transition:background .15s,color .15s}
.mtabs button.on{background:var(--paper);color:var(--ink);box-shadow:0 0 0 1px var(--line)}

.vuoto{padding:34px 18px;display:flex;flex-direction:column;align-items:center;
  gap:6px;text-align:center}
.vuoto b{font-size:14.5px;font-weight:700;color:var(--ink-2)}
.vuoto span{font-size:12.5px;color:var(--faint)}

/* --- margin per set chart ------------------------------------------
   There is no point by point, so the bar tells by how much each set
   was won: it starts from the centre towards whoever took it.
   Proportional bars (25 against 21) would be unreadable: in volleyball
   every set is nearly 50/50 and the gap disappears.                 */
.chart{padding:10px 16px 16px;height:100%;display:flex;flex-direction:column}
.ch-head{
  flex:none;display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:2px 0 12px;
}
.ch-side{
  font-size:10px;font-weight:700;letter-spacing:.06em;color:var(--muted);
  white-space:nowrap;
}
/* The rows share the height: three sets or five, the chart fills the
   same box and the foot stays at the bottom. */
.ch-row{
  display:grid;grid-template-columns:18px 1fr 46px 34px;
  align-items:center;gap:9px;
  flex:1 1 0;min-height:28px;max-height:56px;
}
.ch-sc{font-size:11.5px;color:var(--faint);text-align:right;font-variant-numeric:tabular-nums}
.ch-n{font-size:10px;font-weight:700;color:var(--faint)}
.ch-track{position:relative;height:10px;border-radius:5px;background:var(--sunken)}
.ch-track::before{
  content:"";position:absolute;left:50%;top:-3px;bottom:-3px;
  width:1px;background:var(--line-2);
}
.ch-bar{
  position:absolute;top:0;bottom:0;display:block;
  background:var(--line-2);
  animation:chgrow .42s cubic-bezier(.2,.8,.2,1) both;
}
.ch-bar.me{background:var(--accent)}
.ch-bar.l{border-radius:5px 0 0 5px;transform-origin:right center}
.ch-bar.r{border-radius:0 5px 5px 0;transform-origin:left center}
@keyframes chgrow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.ch-d{
  font-size:11.5px;font-weight:700;text-align:right;color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.ch-tot{
  flex:none;margin-top:auto;display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding-top:12px;border-top:1px solid var(--line);
  font-size:12px;color:var(--muted);
}
.ch-tot b{font-size:15px;font-weight:700;color:var(--ink);letter-spacing:-.01em}

/* The season tag is a PLATE of its own, as on the desk. It sits below
   because the pill is narrow and putting it alongside would break the
   year. */
.pill .tag{
  display:block;margin-top:3px;
  font-size:9.5px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  color:var(--faint);
}
.pill.sel .tag{color:var(--paper);opacity:.7}

}

/* tel/tendina.css */
@media (max-width:899px){
/* ============================================================
   DRAWER AND TOAST: the two corrections to the shared chrome
   ============================================================
   The drawer is drawn by drawer.css, which belongs to every page:
   measures, weights and wording come from there. Two differences
   remain, both of them measurable.

   1. THE CLOSE BUTTON SITS WHERE THE THEME BUTTON SITS. It is the same
      gesture in the same corner (the menu opens with the hamburger on
      the left and closes with the cross on the right) and the header
      already owns that place: 44px of target against the edge, with
      the icon falling twelve pixels inside. The header wins here,
      being the frame common to every page.
   2. THE UNDERLINE. On the board app/base.css takes it off with a
      reset on a, which does not reach down here (it is bounded above
      900px). Down here it comes off the item instead.              */
.menu-top{padding-right:0}
.menu .icon{width:44px;height:48px}
.menu nav a{text-decoration:none}

/* THE TOAST.
   120px from the bottom, which is above the sponsor bar and above the
   switch, where it covers nothing of what is being looked at. On the
   pages that scroll it sits at 30px, because down there is nothing.
   The colour: --paper is the white of the phone, --panel that of the
   board; at night the two are not the same black. */
.toast{
  position:fixed;bottom:120px;
  background:var(--ink);color:var(--paper);
  padding:10px 16px;border-radius:9px;
  font-size:12.5px;font-weight:600;
  max-width:78%;text-align:center;
}

/* The privacy line inside the drawer: it gets tapped, so it needs a
   target tall enough for a thumb. */
.menu-piede a{display:inline-block;padding:6px 0;color:inherit;text-decoration:underline}

}

/* tel/gara.css */
@media (max-width:899px){
/* ============================================================
   THE MATCH CARD: phone
   ============================================================
   Two screens draw a match, the calendar diary and the first team
   panel on the home page, and the markup sits in one place
   (ui/gara.js): so does this sheet.

   The diary stays out of it: .gblock and .gday are how the calendar
   groups matches by day, and they hold only there.
   ============================================================ */

/* ============================================================
   THE CARD OF A MATCH
   Same markup as the day column on the board (ui/gara.js), phone
   measurements: the time column narrows from 74 to 66px and the type
   drops a point and a half, because the usable width here is 390 and
   not 400 inside a 1600 board.
   ============================================================ */
/* The cards of a day TOUCH. Eight pixels apart, with the band at ten,
   the gap between two matches of one day is nearly the gap between two
   different days, and half way down the screen it stops being clear
   whose a card is. The top border comes from the card above (or from
   the band), and the block closes at the foot. */
.dcard{
  display:grid;grid-template-columns:66px minmax(0,1fr);align-items:center;gap:12px;
  margin:0 12px;padding:11px 12px;
  background:var(--paper);border:1px solid var(--line);border-top:0;border-radius:0;
}
.gblock .dcard:last-child{border-radius:0 0 12px 12px}
/* Home and away: the 3px bar on the left, which across the site
   already means "this row is marked". Brand at home, quiet away. */
.dcard.casa{box-shadow:inset 3px 0 0 var(--brand)}
.dcard.via{box-shadow:inset 3px 0 0 var(--line-2)}
/* Every card opens the match sheet, even for a match still to play:
   inside are the full date, the address and how long is left. The
   touch feedback is the one of every list on the phone. */
.dcard.apre:active{background:var(--sunken)}
/* THE STRIP CARRIES THE TIME, the OUTCOME in words and home or away,
   the three things looked at first while scrolling the diary with a
   thumb. The score sits at the end of the two team lines, where the
   result card puts it. */
.dwhen{display:flex;flex-direction:column;align-items:center;gap:3px}
.dwhen b{font-size:18px;font-weight:800;letter-spacing:-.02em;line-height:1.15}
/* PALE green and red, never the solid ones: in a list being scrolled
   a file of saturated blots becomes the only thing visible. The draw
   is neutral. */
.desito{
  padding:1px 5px;border-radius:5px;white-space:nowrap;
  font-size:8.5px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;
}
.dcard.vinta .desito{background:var(--up-fill);color:var(--up)}
.dcard.persa .desito{background:var(--down-fill);color:var(--down)}
.dcard.pari .desito{background:var(--line-2);color:var(--ink)}
.dsede{
  display:flex;align-items:center;gap:3px;
  font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--faint);
}
.dcard.casa .dsede{color:var(--brand)}
.dsede .emo{font-size:12px;line-height:1}
.dinfo{min-width:0;display:flex;flex-direction:column;gap:1px}
/* The title of the card is the COMPETITION, with the round at the end
   of the same line: the team name is in the row, and writing it twice
   serves nobody. */
.dcima{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:3px}
/* THE COMPETITION PLATE IS AN OUTLINE, not a fill: the tournament is
   what tells one match from another, but in a list being scrolled six
   brand fills in a row take the eye before the team names do. The
   reason at length is in app/gara.css.
   The measurements stay the phone ones, a shade narrower: the card has
   less width and the plate must not eat the round number beside it. */
.dcomp{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  border:1px solid var(--brand);border-radius:999px;padding:2px 8px;
  font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--brand);
}
.dgio{flex:none;white-space:nowrap;font-size:10px;font-weight:500;color:var(--faint)}
/* THE TWO TEAMS, HOME ON TOP, THE SCORE AT THE END OF EACH LINE, as
   in the result card of the results screen and with the same language:
   ours in team colour and uppercase, the other plain. Whoever reads it
   knows who hosts without looking for the icon beside, and when our
   line is the lower one it means an away match.
   OUR NAME IS NOT SMALLER. Same size for both, and the weight makes
   the difference: a home team in a smaller size would say the opposite
   of what the colour says. */
.dteam{
  flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:13.5px;font-weight:500;line-height:1.3;color:var(--ink-2);
}
.dteam.noi{font-weight:800;letter-spacing:.02em;text-transform:uppercase;color:var(--brand)}
.drow{display:flex;align-items:baseline;gap:9px}
.dsc{
  flex:none;min-width:12px;text-align:right;
  font-size:14px;font-weight:800;line-height:1.3;letter-spacing:-.02em;color:var(--ink-2);
}
.dcard.attesa .dsc{font-weight:600;color:var(--line-2)}
.ddove{margin-top:3px;font-size:12px;color:var(--muted);overflow-wrap:anywhere}

}

/* tel/calendario.css */
@media (max-width:899px){
/* ============================================================
   THE CALENDAR ON THE PHONE: the diary
   ============================================================
   The TAIL of the phone band for this page: it comes after all the
   shared sheets (tel/base, tel/barre, tel/piede, tel/fogli), because
   it holds both the new rules and the few corrections to those, and a
   correction written before the rule it corrects loses on order and
   does nothing.

   It leans on everything the results screen already has: the .compbar
   at the top with the season pill, the sheets rising from the bottom,
   the sponsor bar at the foot. What belongs to the calendar alone is
   the list: day bands and cards.                                    */

/* The scrolling strip is the reference for the offsets.
   cal-phone.js reads offsetTop of the day headings to know where to
   jump, and offsetTop is measured from the first POSITIONED ancestor:
   without this line that would be the page body, and every offset
   would be out by the height of the header. */
.scroll{position:relative}

/* ============================================================
   THE DAY: THE MOST IMPORTANT ROW ON THE SCREEN
   ============================================================
   In a diary scrolled with a thumb, the one thing that MUST be
   unmistakable is where a day ends and the next one begins: getting it
   wrong means believing a match is on Sunday when it is on Saturday,
   and turning up at the gym a day late. So the day is a band, and it
   shows even when scrolling fast:

     · a solid ground (--sunken) edge to edge, breaking the column of
       cards instead of sitting inside its air;
     · a marked hairline above and below (--line-2, not --line);
     · a 4px brand bar on the left, the same one that marks the chosen
       item across the site;
     · the text in --ink and not in --muted, a point and a half
       larger. */
/* THE DAY ROW IS THE STICKY BAND. While scrolling, the day whose
   matches are being read stays at the top, which is the real question.
   The ground has to be SOLID: the cards scroll under it, and a
   transparent ground would show two rows on top of each other. */
/* THE DAY BLOCK. The gap sits HERE, once, between one block and the
   next. */
.gblock + .gblock{margin-top:18px}
.gblock:last-child{padding-bottom:14px}

.gday{
  position:sticky;top:0;z-index:20;
  margin:0;padding:9px 14px;display:flex;
  background:var(--sunken);
  border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);
  box-shadow:inset 4px 0 0 var(--brand);
}
.gday .d{
  font-size:12px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink);
}
/* Today: the same mark as the board, where the cell number turns
   solid brand. Here there is no cell and the mark goes on the full
   date, but the language is the same. */
.gday.oggi .d{background:var(--brand);color:var(--on-brand);border-radius:5px;padding:2px 7px}

/* THE MATCH CARD lives in tel/gara.css: the home page draws it too.
   That sheet loads BEFORE this one, which corrects a few of its
   measurements inside the diary. */

/* ============================================================
   THE FILTER SHEET
   It rises from the bottom like the competition one, with the same
   mechanics (ui/fogli.js) and the same veil. It stays UP while boxes
   are ticked: it is a filter, not a single choice, and closing it on
   every tap would mean reopening it a dozen times.
   ============================================================ */
/* NO FIXED HEIGHT, and here that is right. The list changes only with
   the season, and changing season closes the sheet: ticking moves
   nothing. A fixed height would leave half a screen of emptiness in a
   year with a single team. The ceiling comes from .sheet (82%), and
   past that the list scrolls. */

/* "Tutte" and "Nessuna": two equal buttons, not one main and one for
   service. Nessuna is a legitimate state (it is how the filter is
   cleared before picking two) and a faded button would say the
   opposite. */
.ftutte{flex:none;display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:0 14px 10px}
.ftutte button{
  padding:11px 0;border-radius:10px;background:var(--sunken);
  font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);
}
.ftutte button:active{background:var(--line)}

.sq{width:100%;display:flex;align-items:center;gap:12px;padding:9px 8px;border-radius:10px;
  text-align:left}
.sq:active{background:var(--sunken)}
/* Ticked: light veil and filled box, like the current stage in the cup
   run. No bar: the box is the mark already, and two marks for one
   state are one too many. */
.sq.on{background:var(--silea-fill)}
.sq .box{
  flex:none;width:22px;height:22px;border-radius:6px;
  border:1.5px solid var(--line-2);background:var(--paper);display:grid;place-items:center;
}
.sq.on .box{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}
.sq .box .ico{width:14px;height:14px}
/* TWO LINES, like the board sidebar: the name on top, the
   competitions below. The sheet is as wide as the screen and names
   reach twenty-eight characters, so the same three precautions hold:
   min-width:0 on all three boxes, and ellipsis on both lines. Without
   them the text box takes the width of its content as a minimum and
   the match count at the end pays for it. */
.sq .txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:0}
.sq .nm{
  min-width:0;font-size:14.5px;font-weight:500;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sq.on .nm{font-weight:700}
.sq .sotto{
  min-width:0;font-size:11.5px;font-weight:500;line-height:1.3;color:var(--faint);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sq.on .sotto{color:var(--muted)}
/* MORE THAN ONE ENTRY, A SINGLE TICK. A team can be entered several
   times under different names (ui/iscrizioni.js) and here it is one
   item: the box lights them all together, and the count at the end is
   the sum of their matches. The item names them all, because the name
   on the shirt changes from one league to the next and whoever looks
   for theirs has to find it. */
.sq .isc{min-width:0;display:flex;flex-direction:column;gap:0}
.sq .isc + .isc{margin-top:6px}
/* A HAIRLINE BETWEEN ONE ITEM AND THE NEXT. An item that names
   several entries (ui/iscrizioni.js) can be four lines tall, and four
   lines in a row with nothing between them read as four items: which
   loses the very thing the grouping says, that those two names are one
   team and tick together.

   THE HAIRLINE SITS IN THE GAP, not on the item. Drawn as a border it
   becomes part of the item, and the item is a rounded slab: the ticked
   one would come out square on top and round at the bottom. This way
   the slab stays whole and the line runs through the air between them.
   Above every item but the first, so none is left hanging at the end
   of the list. */
#squadre .sq{position:relative}
#squadre .sq + .sq{margin-top:9px}
#squadre .sq + .sq::before{
  content:"";position:absolute;left:0;right:0;top:-5px;height:1px;background:var(--line);
}
.sq .n{flex:none;font-size:12.5px;font-weight:600;color:var(--faint)}
.sq.on .n{color:var(--brand)}

/* On the phone the cards of a day touch: the gap here cannot be air,
   it would open a hole inside the day block. It is a more marked
   hairline, the same colour as the block border. */
.dcard.stacco{border-top:1px solid var(--line-2)}

}

/* motion.css */
/* REDUCED MOTION.
   ================
   Always the last sheet of every page: it has to win over everything
   and media queries add no specificity, so position is its only
   weapon.

   Transitions go off, animations jump to their end. A .01ms duration
   lands the animation on its final state, which is where the content
   is meant to be read.                                               */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    transition:none !important;
    animation-duration:.01ms !important;
  }
  .card:hover{transform:none}
  /* The phone strip jumps to the point instead of gliding there.
     Changing matchday scrolls back to the top, and that glide is
     exactly the unexpected motion to remove. */
  .scroll{scroll-behavior:auto}
  /* On the sparrow the generic rule makes things worse: an infinite
     animation cut to .01ms repeats the flight thousands of times a
     second and the bird flickers. Here it simply stops, still at
     mid flight. */
  .bird{animation:none !important;opacity:var(--bird-op);
        transform:translate3d(calc(50cqw - 50%),-50%,0)}
}
