@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');

/* ============================================================
   BOXALMATCH — legacy subpage theme
   ------------------------------------------------------------
   Drop-in replacement for the old css/main.css. Same selector
   contract as the original (so js/main.js and every existing
   page keeps working untouched) — only the visual design
   tokens change, to match the new brand: dark ground, brand
   green accent, Inter typeface, calmer motion.

   Per-page accent: this file reads --primary-color and
   --primary-shade-color from :root. The base value below is
   the default brand green; guild-specific files (main_*.css)
   override those two variables and then @import this file.
   ============================================================ */

:root {
    --main-bg-color: #000000;
    --main-bg-color-fade-5: rgba(0, 0, 0, 0.6);
    /* the brand green, sampled from the wordmark (see css/style.css). Hover
       goes lighter rather than darker: the button fill carries dark ink, and
       darkening it drops that below 4.5:1. */
    --primary-color: #00B81C;
    --primary-shade-color: #00CE1F;
    --secundary-color: #6e6e73;

    --ink: #ffffff;
    --ink-muted: #a8a8ae;
    --surface: #0c0c0e;
    --surface-2: #050506;
    --hair: #2a2a2e;
    /* the edge of anything clickable or typable, where WCAG wants 3:1 */
    --hair-strong: #5a5a63;
    /* Tiles sit on pure black, so a flat near-black fill disappears into the
       page. These are frosted greys instead: a translucent white wash with a
       blur behind it and a lit top edge, which reads as a raised surface. */
    --glass: rgba(255, 255, 255, 0.055);
    --glass-2: rgba(255, 255, 255, 0.085);
    --glass-blur: blur(26px) saturate(150%);
    --glass-strong: rgba(255, 255, 255, 0.09);
    --glass-hair: rgba(255, 255, 255, 0.12);
    --r: 18px;
    --r-lg: 26px;
    --shadow: 0 4px 24px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 18px 56px rgba(0, 0, 0, 0.6);
    --rail-bleed: clamp(16px, 6vw, 90px);
    --font: "Inter", -apple-system, BlinkMacSystemFont, "SF Pro Display",
            "Helvetica Neue", Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
[id] { scroll-margin-top: 72px; }

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

.mobile-nav {
    display: none;
}

.mb-1 {
    margin: 0;
    margin-bottom: 0.9em;
}

body {
    background-color: var(--main-bg-color);
    background-image: none;
}

body, html {
    font-family: var(--font);
    background-color: var(--main-bg-color);
    color: var(--ink);
    margin: 0;
    font-size: 17px;
    line-height: 1.47;
    letter-spacing: -0.012em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--ink);
    font-weight: 600;
    letter-spacing: -0.025em;
}

a {
    color: var(--primary-color);
    text-decoration: none;
    font-weight: 600;
}
a:hover { text-decoration: underline; }

/* ---------- IT/EN language toggle ---------- */
[data-lang="it"] [lang="en"] { display: none !important; }
[data-lang="en"] [lang="it"] { display: none !important; }

.lang-toggle {
    display: inline-flex;
    align-items: center;
    border: 1px solid var(--hair-strong);
    border-radius: 980px;
    overflow: hidden;
}

.lang-toggle button {
    background: transparent;
    color: var(--ink);
    opacity: 0.7;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.02em;
    padding: 5px 11px;
    width: auto;
    margin: 0;
    border-radius: 0;
}

.lang-toggle button:hover { background-color: transparent; opacity: 1; }

/* 24px tall on a phone, right on the WCAG floor and awkward with a thumb. */
@media (max-width: 820px) {
    .lang-toggle button { padding: 8px 13px; }
}

.lang-toggle button.on {
    background-color: var(--ink);
    color: var(--main-bg-color);
    opacity: 1;
}

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

h1 { font-size: 2.8em; }
h2 { font-size: 2.1em; }
h3 { font-size: 1.7em; }
h4 { font-size: 1.4em; }
h5 { font-size: 1.2em; }
h6 { font-size: 1.05em; }

button {
    background-color: var(--primary-color);
    border: 1px solid transparent;
    border-radius: 999px;
    color: #06210c;
    padding: 12px;
    width: 100%;
    font-weight: 600;
    font-family: var(--font);
    cursor: pointer;
    margin-top: 10px;
    transition: background-color .2s;
}
button:hover { background-color: var(--primary-shade-color); }

.margin-2 { margin: 0.4em 0; }
.margin-3 { margin: 0.8em 0; }

.container {
    width: 100%;
    max-width: 980px;
    margin: 0 auto;
    padding: 0 20px;
    box-sizing: border-box;
}

main > section.container {
    padding-top: 64px;
    padding-bottom: 64px;
}

main > section.container > h1.highlight {
    text-align: center;
    font-size: clamp(32px, 4.2vw, 48px);
    letter-spacing: -0.03em;
    margin-bottom: 44px;
    color: var(--guild-color, var(--ink));
}

/* A short rule under each section title, in the page's accent. On a guild
   page that is the guild's colour; everywhere else it is the BOXALMATCH
   green, which is why it is --primary-color and not --guild-color. */
main > section.container > h1.highlight::after {
    content: "";
    display: block;
    width: 54px;
    height: 2px;
    margin: 18px auto -8px;
    border-radius: 2px;
    background: var(--primary-color);
    opacity: 0.85;
}

main > section.container h2 {
    text-align: center;
    font-size: clamp(26px, 3vw, 36px);
    letter-spacing: -0.03em;
    margin-top: 56px;
    margin-bottom: 20px;
}

.container-fluid {
    width: 100%;
    min-width: 100%;
}

.hidden {
    opacity: 0 !important;
    height: 0 !important;
    width: 0 !important;
    overflow: hidden !important;
}

/* ---------- navigation ---------- */
/* Named properties, not `all`. `all` animated the focus outline too, so a
   keyboard user's ring faded in over 200ms instead of appearing, and every
   descendant carried a transition for properties that never change. */
#main-header, #main-header * {
    transition: opacity 0.2s, background-color 0.2s, color 0.2s, border-color 0.2s;
}

/* Same bar as the home page: sticky from the top, glass from the top, one
   z-index. It used to sit at rgba(0,0,0,0.1) until a .scrolled class swapped
   it to position:fixed, which both left the links floating over the hero art
   unreadably and jumped the page as the header left the flow. .scrolled now
   only deepens the fill a little, as on the home page. */
#main-header {
    position: sticky;
    top: 0;
    z-index: 9000;
    background-color: rgba(0, 0, 0, 0.72);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-bottom: 1px solid var(--hair);
}

/* .scrolled used to deepen the fill to 0.9, which made the bar noticeably
   more solid than the home page's the moment you scrolled — exactly when the
   artwork passing behind it makes the glass worth having. The class is still
   toggled by the legacy script; it just no longer changes the fill. */

header > nav > ul {
    margin: 0;
    padding: 0;
    display: flex;
    list-style: none;
    justify-content: flex-start;
    align-items: center;
    height: 48px;
    min-height: 48px;
    max-width: 1024px;
    margin-left: auto;
    margin-right: auto;
    padding-left: 22px;
    padding-right: 22px;
}

header > nav > ul > li {
    margin: 0 0 0 26px;
    position: relative;
}

/* The brand used to be pinned left here. The wordmark has moved onto the
   artwork, and the way back up the site took its place: every sub-page now
   carries it in the bar rather than buried in a [Torna alla Home] at the end
   of the hero paragraph, where it was easy to miss and gone the moment you
   scrolled. */
header > nav > ul > li.lang-toggle {
    flex: 1 1 0;
    display: flex;
    justify-content: flex-end;
    /* The pill outline is on .lang-toggle itself, and this <li> IS that
       element — so growing it to balance the brand stretched the border into
       a long empty capsule. The outline moves onto the two buttons here, and
       only here: on a phone js lifts this same node into the bar, where it
       is not a flex item and keeps its own pill. */
    border: 0;
    border-radius: 0;
    overflow: visible;
}

header > nav > ul > li.lang-toggle > button {
    border: 1px solid var(--hair-strong);
}

header > nav > ul > li.lang-toggle > button:first-of-type {
    border-radius: 980px 0 0 980px;
    border-right: 0;
}

header > nav > ul > li.lang-toggle > button:last-of-type {
    border-radius: 0 980px 980px 0;
}

/* The brand, as on the home page: the mark a little taller than the wordmark,
   which is set to its cap height — matching the two exactly leaves the round
   mark looking smaller than the letters beside it. */
header > nav > ul > li.nav-brand {
    flex: 1 1 0;
    margin-left: 0;
}

header > nav > ul > li.nav-brand > a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    opacity: 1;
}

header > nav > ul > li.nav-brand img { width: auto; display: block; }
header > nav > ul > li.nav-brand .nav-mark { height: 22px; }
header > nav > ul > li.nav-brand .nav-word { height: 15px; }

/* The way back to the event's own home, on an inner page. It keeps the
   chevron the brand used to carry: it points up a level, which is exactly
   what it does, and the logo beside it goes somewhere else entirely. */
header > nav > ul > li.nav-up > a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

header > nav > ul > li.nav-home > a {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    opacity: 0.72;
}

header > nav > ul > li.nav-home > a:hover {
    opacity: 1;
    color: var(--primary-color);
}

/* Sized and nudged by hand: the chevron's own side bearing leaves it looking
   detached from the word otherwise. */
.nav-home-ic {
    font-size: 1.25em;
    line-height: 1;
    transform: translateY(-1px);
}

/* Exactly the home page's nav links: same size, same weight, same dim-to-full
   opacity on hover, no padding (which was making this bar 54px against the
   home page's 48px) and no underline under the active item — the home page
   marks nothing, and the rule drew a green line across the foot of the bar. */
header > nav > ul > li > a {
    position: relative;
    text-decoration: none;
    font-size: 15px;
    font-weight: 400;
    letter-spacing: -0.01em;
    color: var(--ink);
    opacity: 0.85;
    display: block;
    padding: 0;
}

header > nav > ul > li:hover > a,
header > nav .active > a {
    opacity: 1;
}

/* ---------- slider / hero ----------
   The hero used to run to max-height:100vh, so every page opened on a full
   screen of artwork and the content began below the fold — on a laptop that
   was 853px of scrolling before the first word. It is now a band, and it
   dissolves into the page rather than ending on a cut edge.

   Figure and caption are stacked with grid rather than absolute positioning.
   The caption used to be absolutely placed at top:26% and its entrance
   animation ends on transform:none — which would have wiped out the
   translate(-50%) that centring it that way needs. Stacking both children in
   one grid cell sidesteps that: the caption centres by alignment, and the
   animation keeps the transform to itself. */
.slider {
    display: grid;
    isolation: isolate;
}

.slider > figure,
.slider > .slide-caption {
    grid-area: 1 / 1;
}

.slider > figure {
    margin: 0;
    position: relative;
}

.slider > figure > img {
    display: block;
    width: 100%;
    height: clamp(300px, 52vh, 520px);
    object-fit: cover;
}

/* Darkens the top so the nav keeps its footing, holds a scrim behind the
   caption, and takes the foot of the image all the way down to the page
   colour — which is what makes the artwork end without a seam. */
.slider > figure::after {
    content: "";
    position: absolute;
    inset: 0;
    /* Two layers, the guild wash on top of the black ramp. --guild-rgb is a
       bare "r, g, b" triple because rgba() needs the channels, not a colour —
       and unset it resolves to 0,0,0, which is transparent at these alphas
       and leaves the ramp alone on every non-guild page. */
    background:
        linear-gradient(to bottom,
            rgba(var(--guild-rgb, 0, 0, 0), 0.20) 0,
            rgba(var(--guild-rgb, 0, 0, 0), 0.07) 45%,
            rgba(var(--guild-rgb, 0, 0, 0), 0.16) 78%,
            transparent 100%),
        linear-gradient(to bottom,
            rgba(0, 0, 0, 0.62) 0,
            rgba(0, 0, 0, 0.20) 26%,
            rgba(0, 0, 0, 0.42) 62%,
            rgba(0, 0, 0, 0.86) 86%,
            var(--main-bg-color) 100%);
}

.slider > .slide-caption {
    /* No panel any more: the wordmark and the copy sit on the artwork, which
       is the point of moving the logo out of the header. The gradient above
       does the work the frosted card used to do. */
    background-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border-radius: 0;
    color: var(--ink);
    position: relative;
    z-index: 1;
    align-self: center;
    justify-self: center;
    width: min(760px, 88%);
    padding: 0 22px;
    text-align: center;
    opacity: 0;
    animation: legacy-rise .9s cubic-bezier(.2,.7,.3,1) .1s forwards;
}

/* ---------- the event wordmark, on the artwork ----------
   It used to sit in the header at 28px with brightness(0) invert(1) over it,
   which threw away the colour it was drawn with and left a smudge. Here it is
   the masthead, in its own colours, at a size worth reading. tools/hero_logo.py
   trims each one to its alpha box first, so the three events match in apparent
   size rather than in canvas size. */
.slider .hero-logo {
    margin: 0;
    font-size: 0;
    line-height: 0;
}

.slider .hero-logo > img,
.slider .hero-mark {
    display: block;
    width: min(420px, 74%);
    height: auto;
    margin: 0 auto 20px;
    /* Two shadows: a wide soft one to lift the whole mark off busy artwork,
       and a tight dark one so the outline stays crisp against light patches. */
    filter: drop-shadow(0 8px 30px rgba(0, 0, 0, 0.85))
            drop-shadow(0 1px 3px rgba(0, 0, 0, 0.9));
}

/* On the inner pages the page's own title is the heading, so the mark is a
   brand signature above it and steps down in size. */
.slider .hero-mark {
    width: min(250px, 54%);
    margin-bottom: 16px;
}

@keyframes legacy-rise {
    from { opacity: 0; transform: translateY(22px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .slider > .slide-caption { animation: none; opacity: 1; }
}

/* On a guild page the hero title takes the guild's own colour. --guild-color
   is set only by the nine main_<guild>.css files, so everywhere else this
   falls back to white and nothing changes — that is what keeps one rule in
   the shared stylesheet from turning every event's hero green. Each of those
   colours was picked to clear 4.5:1 on black already; the shadow below covers
   the artwork it actually sits on. */
.slider > .slide-caption h1,
.slider > .slide > .slide-caption h1 {
    color: var(--guild-color, var(--ink));
    text-shadow: 0 2px 18px rgba(0, 0, 0, 0.9), 0 1px 3px rgba(0, 0, 0, 0.85);
    font-size: clamp(38px, 5.4vw, 68px);
    margin: 0 0 .35em;
    letter-spacing: -0.035em;
    line-height: 1.05;
}

.slider > .slide-caption p {
    color: var(--ink);
    /* Without the frosted card behind it this sits straight on the artwork,
       so it carries its own contrast rather than relying on the panel. */
    text-shadow: 0 1px 12px rgba(0, 0, 0, 0.9), 0 1px 3px rgba(0, 0, 0, 0.8);
    font-size: clamp(17px, 1.5vw, 21px);
    line-height: 1.4;
    letter-spacing: -0.015em;
    max-width: 46ch;
    margin-left: auto;
    margin-right: auto;
}

/* ---------- episode carousel (peek rail, scroll-snap) ---------- */
.episodes {
    position: relative;
    /* auto, not 100%: the rail bleeds past its container by --rail-bleed on
       both sides, and a fixed 100% left the negative right margin with
       nothing to expand into, so the whole rail sat one bleed left of
       centre. */
    width: auto;
    background-color: transparent;
    border-radius: 0;
    display: flex;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 20px;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    scroll-padding-left: 0;
    padding: 4px 0 8px;
    /* peek: the rail bleeds past the container so neighbours show at the edges */
    margin-left: calc(var(--rail-bleed) * -1);
    margin-right: calc(var(--rail-bleed) * -1);
    padding-left: var(--rail-bleed);
    padding-right: var(--rail-bleed);
    scrollbar-width: none;
    -ms-overflow-style: none;
}

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

/* The bleed may never exceed the space between the container and the window,
   or the page itself scrolls sideways (it did, by 19px, at exactly 1024px).
   Inside the rail, 100% is the container's content box, so (100vw - 100%) / 2
   is precisely the gutter left over on each side; the 8px keeps a classic
   scrollbar — which 100vw counts and clientWidth does not — from eating the
   margin. Below 821px the rail is deliberately flush with the screen edge and
   --rail-bleed is set to the gutter directly. */
@media (min-width: 821px) {
    .episodes {
        --rail-bleed: min(clamp(16px, 6vw, 90px), calc((100vw - 100%) / 2 - 8px));
    }
}

/* a rail with a single item is centred rather than left-aligned */
.episodes.is-single { justify-content: center; }

.episode {
    position: relative;
    flex: 0 0 auto;
    width: min(76%, 780px);
    aspect-ratio: 16 / 10;
    margin: 0;
    opacity: 1;
    z-index: auto;
    scroll-snap-align: center;
    border-radius: var(--r-lg);
    overflow: hidden;
    background-color: var(--glass);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-hair);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset, var(--shadow-lg);
    transition: transform .4s cubic-bezier(.2,.7,.3,1), border-color .3s;
}

.episode:hover { border-color: rgba(255, 255, 255, 0.18); }

.episode > img {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    /* contain, not cover: the rails mix posters, score tables and photos and
       cropping would cut information out of the frame */
    object-fit: contain;
    display: block;
    background-color: transparent;
}

.episode > figcaption {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    padding: 28px 20px 16px;
    box-sizing: border-box;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0));
    color: #ffffff;
    text-align: left;
    font-size: 0.95em;
}

/* ---------- season / content blocks ---------- */
.season > h2, .season p { margin: 0.8em 0; }

.season > h2, .season > h1 { font-size: 1.7em; }

/* the rail inside a .season block keeps the same peek behaviour */
.season > .episodes {
    position: relative;
    height: auto;
    border-radius: 0;
    overflow-x: auto;
    overflow-y: hidden;
}

#episode-number {
    position: absolute;
    right: 0;
    background: rgba(0, 0, 0, 0.55);
    padding: 10px 14px;
    z-index: 2;
    font-family: var(--font);
    font-size: 0.8em;
}

/* The "No. #n" counter is replaced by a row of position dots, so the pill is
   hidden rather than removed: the markup for it is in 24 legacy pages and the
   old inline scripts still reach for it. */
.episode-number { display: none !important; }

/* Instagram-style position dots. A live control, not decoration: each dot is
   a button that scrolls its slide into view, and the row is a tablist so it
   works from the keyboard. Rails longer than the window show a sliding set
   with the outer dots shrinking, rather than a 12-dot centipede. */
.rail-dots {
    --dot-slot: 14px;
    order: 2;
    overflow: hidden;
    margin: 0 4px;
    max-width: calc(var(--dot-slot) * 7);
}

.rail-dots > .dots-track {
    display: flex;
    align-items: center;
    transition: transform .3s cubic-bezier(.2, .7, .3, 1);
}

.rail-dots button {
    /* the 14px slot is width + margins, not flex-basis: a basis wider than the
       height would stretch each dot into a pill */
    flex: 0 0 7px;
    width: 7px;
    height: 7px;
    padding: 0;
    margin: 0 3.5px;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.26);
    cursor: pointer;
    transition: background-color .25s, transform .25s, opacity .25s;
}

.rail-dots button:hover { background: rgba(255, 255, 255, 0.45); }

/* Same trick as the home page: a transparent 28px pseudo-element gives the
   7px dot a finger-sized target without changing the layout. */
.rail-dots button { position: relative; }
.rail-dots button::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 28px;
    height: 28px;
    transform: translate(-50%, -50%);
}

.rail-dots button.on {
    background: var(--primary-color);
    transform: scale(1.25);
}

.rail-dots button.near { transform: scale(.72); opacity: .75; }
.rail-dots button.far  { transform: scale(.45); opacity: .5; }

.season > .episodes,
.season > .episodes > .episode {
    margin: 0;
}

.season > .episodes > .episode {
    position: relative;
    height: auto;
    z-index: auto;
}

.season > .episodes > .episode > img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background-color: transparent;
    transition: transform 0.6s cubic-bezier(.2,.7,.3,1);
}

.season > .episodes > .episode > img:hover {
    transform: scale(1.04);
}

.season > .episodes > .episode figcaption {
    position: absolute;
    bottom: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0));
    width: 100%;
    padding: 28px 20px 16px;
    box-sizing: border-box;
}

/* ---------- carousel controls (centred beneath the rail) ---------- */
.controls {
    position: static;
    width: 100%;
    padding: 0;
    margin-top: 18px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 12px;
}

.controls > .prev { order: 1; }
.controls > .next { order: 3; }

.controls > button {
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid var(--hair);
    border-radius: 999px;
    cursor: pointer;
    transition: background-color .2s, border-color .2s, transform .2s, opacity .2s;
    font-weight: 500;
    font-size: 15px;
    line-height: 1;
    width: 42px;
    height: 42px;
    padding: 0;
    color: var(--ink);
    margin: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(16px) saturate(140%);
    -webkit-backdrop-filter: blur(16px) saturate(140%);
}

.controls > button:hover {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.28);
    color: var(--ink);
    transform: scale(1.06);
}

.controls > button:disabled {
    opacity: 0.32;
    cursor: default;
    transform: none;
}

.controls .next, .controls .prev { position: static; right: auto; left: auto; }

/* a rail plus its controls stack vertically */
.episodes-wrap {
    display: flex;
    flex-direction: column;
}

#episodes-group > .controls { z-index: 3; }

#episodes-group > .episode {
    position: relative;
    top: auto;
    opacity: 1;
}

/* ---------- character / feature cards (tile grid, matching the main site's event cards) ---------- */
/* Flex rather than grid, for one reason: a partial last row. Grid's
   justify-content centres the whole set of tracks but still seats a lone
   tile in the first of them, so a page with one tile, or with four across
   three columns, left the remainder hanging off to the left. Flex wrap
   centres every row including the last.

   flex-grow stays 0 on the tiles: letting them grow would make a single
   tile span the container, which is what this is meant to stop. */
.character-profile {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 26px;
    align-items: stretch;
}

.character-profile > h1.highlight {
    flex: 0 0 100%;
}

.character-profile > .character {
    /* Grow to fill a full row — three across the 940px container, as the
       grid gave before — but never past a tile's worth. The cap is what
       stops a lone tile spanning the container, so a short row stays
       tile-sized and lands in the middle. */
    flex: 1 1 270px;
    max-width: 330px;
    position: relative;
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--glass);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border: 1px solid var(--glass-hair);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06) inset, 0 12px 48px rgba(0, 0, 0, 0.4);
    transition: transform 0.3s, box-shadow 0.3s, background-color 0.3s;
}

.character-profile > .character:hover {
    background-color: var(--glass-2);
    transform: translateY(-4px);
    box-shadow: 0 16px 56px rgba(0, 0, 0, 0.55);
}

.character-profile > .character > figure {
    overflow: hidden;
    height: 180px;
    margin: 0;
    border-radius: 0;
}

.character-profile > .character > figure > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s;
}

.character-profile > .character > figure > img:hover {
    transform: scale(1.08);
}

.character-profile > .character > .character-bio {
    position: static;
    right: auto;
    top: auto;
    height: auto;
    min-height: 0;
    flex: 1;
    background-color: transparent;
    border: none;
    padding: 22px 22px 24px;
    width: auto;
    border-radius: 0;
    box-shadow: none;
}

.character-profile > .character > .character-bio > h1 {
    font-size: 1.2em;
    letter-spacing: -0.02em;
}

/* ---------- tables (standings / stats) — glass ---------- */

/* Some score matrices are wider than the page. Unwrapped they pushed the
   document itself sideways, which threw every other element off centre. JS
   gives each table a scrolling box: narrow ones still centre inside it, wide
   ones scroll within it and the page stays put. */
.table-scroll {
    max-width: 100%;
    overflow-x: auto;
    margin: 18px auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.table-scroll > table { margin: 0 auto; }

/* On a phone the legacy inline widths are dropped so every table sizes itself
   against the column: one that fits wraps its text inside it, one that cannot
   (the 16- and 30-column score matrices) keeps its natural width and scrolls
   inside .table-scroll, leaving the page itself where it is. Cell padding
   comes down a little to buy width back.

   Note there is deliberately no overflow-wrap here. Letting cells break
   anywhere does make a table fit, but it also lowers every column's
   min-content width, so the table collapses to its narrowest possible layout
   and words snap mid-syllable — "Marin / e", "TOTA / LE". Cells that really
   have nowhere to break are handled at the source instead: initTableScroll()
   adds zero-width breaks after the commas in the run-together player lists. */
@media (max-width: 820px) {
    /* The scrolling box bleeds to the screen edge like the photo rails do:
       a wide table gets the whole width to work with, and running visibly off
       the edge of the screen is the only hint a phone gives that it scrolls. */
    .table-scroll {
        /* none, not the 100% the desktop rule carries: 100% is the text
           column, and with the bleed's padding inside it the box would be
           narrower than where it started. */
        max-width: none;
        margin-left: calc(var(--rail-bleed) * -1);
        margin-right: calc(var(--rail-bleed) * -1);
        padding-left: var(--rail-bleed);
        padding-right: var(--rail-bleed);
    }

    .table-scroll > table {
        width: auto !important;
        min-width: 0;
    }

    .table-scroll > table td,
    .table-scroll > table th {
        padding: 9px 10px;
    }
}

table {
    border-radius: var(--r);
    overflow: hidden;
    border-collapse: separate !important;
    border-spacing: 0;
    background: var(--glass);
    backdrop-filter: blur(22px) saturate(150%);
    -webkit-backdrop-filter: blur(22px) saturate(150%);
    border: 1px solid var(--glass-hair) !important;
    box-shadow: var(--shadow);
    color: var(--ink);
    /* auto, not 0: the legacy markup sets width inline (40%, 60%, 80%), which
       left every table hard against the left edge of the container */
    margin: 18px auto;
}

/* The legacy HTML hard-codes its table colours inline — they were picked for a
   white page, so on the dark theme they range from ugly to unreadable (black on
   black at 1.2:1, white-on-orange chips at 2.1:1). Inline styles beat stylesheet
   rules, so each value is re-mapped here with !important: flat fills become
   transparent glass, and the hues that carry meaning (headers, player chips,
   guild names, medals) survive as a translucent tint with legible ink.
   The `color:` selectors anchor on `^color:` / `;color:` so they can never
   collide with a `background-color:` declaration of the same value. */

/* Table headers: neutral glass. These are chrome, not data. */
table thead tr,
table thead th {
    background-color: var(--glass-strong) !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* Green fills stay green. They used to share the rule above, which is how a
   winners' row and a table header ended up the same grey — the one distinction
   in the legacy markup that was actually carrying meaning. The tint is dark
   enough that white ink sits at ~11:1 on it, so the hue is free to be obvious.
   font-weight is a second, non-colour cue, since a green row means something
   (qualified, won) and colour alone should not be the only way to see it. */
[style*="background-color: #228B22"],
[style*="background-color:#228B22"],
[style*="background: #228B22"],
[style*="background:#228B22"],
[style*="background-color: #107C10"],
[style*="background-color:#107C10"],
[style*="background: #107C10"],
[style*="background:#107C10"],
[style*="background-color: #32CD32"],
[style*="background-color:#32CD32"],
[style*="background: #32CD32"],
[style*="background:#32CD32"],
[style*="background-color: #2ecc71"],
[style*="background-color:#2ecc71"],
[style*="background: #2ecc71"],
[style*="background:#2ecc71"] {
    background-color: rgba(0, 184, 28, 0.22) !important;
    background-image: none !important;
    color: var(--ink) !important;
    font-weight: 600;
}

/* The legacy page used four different light fills and they were not
   interchangeable: white was the default cell, #f2f2f2 was zebra striping,
   #d3d3d3 and grey labelled guild-name cells, #e6ccff marked a category of
   row. Collapsing all four to transparent — which is what this rule used to do
   — threw away the striping and the labels along with the glare. They are
   separated below, each as a step on the same neutral ramp so the original
   ordering survives, except the purple which keeps its hue. */

/* default cells: nothing to say, let the glass show */
[style*="background-color: white"],
[style*="background-color:white"],
[style*="background: white"],
[style*="background:white"],
[style*="background-color: #fff"],
[style*="background-color:#fff"],
[style*="background: #fff"],
[style*="background:#fff"] {
    background-color: transparent !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* zebra striping */
[style*="background-color: #f2f2f2"],
[style*="background-color:#f2f2f2"],
[style*="background: #f2f2f2"],
[style*="background:#f2f2f2"] {
    background-color: rgba(255, 255, 255, 0.035) !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* label cells, a step up the ramp from the striping */
[style*="background-color: #d3d3d3"],
[style*="background-color:#d3d3d3"],
[style*="background: #d3d3d3"],
[style*="background:#d3d3d3"],
[style*="background-color: grey"],
[style*="background-color:grey"],
[style*="background: grey"],
[style*="background:grey"] {
    background-color: rgba(255, 255, 255, 0.10) !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* the purple category rows keep their hue */
[style*="background-color: #e6ccff"],
[style*="background-color:#e6ccff"],
[style*="background: #e6ccff"],
[style*="background:#e6ccff"] {
    background-color: rgba(167, 139, 250, 0.20) !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* dark fills -> a faint glass tint rather than flat black slabs */
[style*="background-color: black"],
[style*="background-color:black"],
[style*="background: black"],
[style*="background:black"],
[style*="background-color: #000"],
[style*="background-color:#000"],
[style*="background: #000"],
[style*="background:#000"],
[style*="background-color: #555555"],
[style*="background-color:#555555"],
[style*="background: #555555"],
[style*="background:#555555"],
[style*="background-color: #555"],
[style*="background-color:#555"],
[style*="background: #555"],
[style*="background:#555"] {
    background-color: rgba(255, 255, 255, 0.045) !important;
    background-image: none !important;
    color: var(--ink) !important;
}

/* player chips: solid #FF8C00 under white text was 2.1:1 */
[style*="background-color: #FF8C00"],
[style*="background-color:#FF8C00"],
[style*="background: #FF8C00"],
[style*="background:#FF8C00"],
[style*="background-color: #ff8c00"],
[style*="background-color:#ff8c00"],
[style*="background: #ff8c00"],
[style*="background:#ff8c00"] {
    background-color: rgba(224, 132, 38, 0.10) !important;
    background-image: none !important;
    color: #FFC78A !important;
}

[style*="background-color: #FF8C00"] *,
[style*="background-color:#FF8C00"] *,
[style*="background: #FF8C00"] *,
[style*="background:#FF8C00"] *,
[style*="background-color: #ff8c00"] *,
[style*="background-color:#ff8c00"] *,
[style*="background: #ff8c00"] *,
[style*="background:#ff8c00"] * {
    color: #FFC78A !important;
}

/* medal fills keep their metal as a tint — gold */
[style*="background-color: #d4af37"],
[style*="background-color:#d4af37"],
[style*="background: #d4af37"],
[style*="background:#d4af37"],
[style*="background-color: #D4AF37"],
[style*="background-color:#D4AF37"],
[style*="background: #D4AF37"],
[style*="background:#D4AF37"] {
    background-color: rgba(212, 175, 55, 0.18) !important;
    background-image: none !important;
    color: #F2D777 !important;
}

/* medal fills keep their metal as a tint — silver */
[style*="background-color: #c0c0c0"],
[style*="background-color:#c0c0c0"],
[style*="background: #c0c0c0"],
[style*="background:#c0c0c0"],
[style*="background-color: #C0C0C0"],
[style*="background-color:#C0C0C0"],
[style*="background: #C0C0C0"],
[style*="background:#C0C0C0"] {
    background-color: rgba(192, 192, 192, 0.10) !important;
    background-image: none !important;
    color: #DCDCDC !important;
}

/* medal fills keep their metal as a tint — bronze */
[style*="background-color: #cd7f32"],
[style*="background-color:#cd7f32"],
[style*="background: #cd7f32"],
[style*="background:#cd7f32"],
[style*="background-color: #CD7F32"],
[style*="background-color:#CD7F32"],
[style*="background: #CD7F32"],
[style*="background:#CD7F32"] {
    background-color: rgba(205, 127, 50, 0.18) !important;
    background-image: none !important;
    color: #EAA877 !important;
}

/* Inline text colours: every value below was chosen against a white page.
   Each is lifted to its dark-theme equivalent — same hue, >= 4.5:1 ink. */

/* light-page ink (white or black) -> the theme's ink */
[style^="color: white"],
[style^="color:white"],
[style*=";color: white"],
[style*=";color:white"],
[style*="; color: white"],
[style*="; color:white"],
[style^="color: #fff"],
[style^="color:#fff"],
[style*=";color: #fff"],
[style*=";color:#fff"],
[style*="; color: #fff"],
[style*="; color:#fff"],
[style^="color: black"],
[style^="color:black"],
[style*=";color: black"],
[style*=";color:black"],
[style*="; color: black"],
[style*="; color:black"],
[style^="color: #000"],
[style^="color:#000"],
[style*=";color: #000"],
[style*=";color:#000"],
[style*="; color: #000"],
[style*="; color:#000"],
[style^="color: #f2f2f2"],
[style^="color:#f2f2f2"],
[style*=";color: #f2f2f2"],
[style*=";color:#f2f2f2"],
[style*="; color: #f2f2f2"],
[style*="; color:#f2f2f2"],
[style^="color: #d3d3d3"],
[style^="color:#d3d3d3"],
[style*=";color: #d3d3d3"],
[style*=";color:#d3d3d3"],
[style*="; color: #d3d3d3"],
[style*="; color:#d3d3d3"] {
    color: var(--ink) !important;
}

/* muted ink */
[style^="color: grey"],
[style^="color:grey"],
[style*=";color: grey"],
[style*=";color:grey"],
[style*="; color: grey"],
[style*="; color:grey"],
[style^="color: #555555"],
[style^="color:#555555"],
[style*=";color: #555555"],
[style*=";color:#555555"],
[style*="; color: #555555"],
[style*="; color:#555555"],
[style^="color: #555"],
[style^="color:#555"],
[style*=";color: #555"],
[style*=";color:#555"],
[style*="; color: #555"],
[style*="; color:#555"] {
    color: var(--ink-muted) !important;
}

/* pale lilac */
[style^="color: #e6ccff"],
[style^="color:#e6ccff"],
[style*=";color: #e6ccff"],
[style*=";color:#e6ccff"],
[style*="; color: #e6ccff"],
[style*="; color:#e6ccff"] {
    color: #DCC6FF !important;
}

/* greens */
[style^="color: #228B22"],
[style^="color:#228B22"],
[style*=";color: #228B22"],
[style*=";color:#228B22"],
[style*="; color: #228B22"],
[style*="; color:#228B22"],
[style^="color: #107C10"],
[style^="color:#107C10"],
[style*=";color: #107C10"],
[style*=";color:#107C10"],
[style*="; color: #107C10"],
[style*="; color:#107C10"],
[style^="color: #32CD32"],
[style^="color:#32CD32"],
[style*=";color: #32CD32"],
[style*=";color:#32CD32"],
[style*="; color: #32CD32"],
[style*="; color:#32CD32"],
[style^="color: #2ecc71"],
[style^="color:#2ecc71"],
[style*=";color: #2ecc71"],
[style*=";color:#2ecc71"],
[style*="; color: #2ecc71"],
[style*="; color:#2ecc71"],
[style^="color: forestgreen"],
[style^="color:forestgreen"],
[style*=";color: forestgreen"],
[style*=";color:forestgreen"],
[style*="; color: forestgreen"],
[style*="; color:forestgreen"] {
    color: #4FD97A !important;
}

/* oranges */
[style^="color: #FF8C00"],
[style^="color:#FF8C00"],
[style*=";color: #FF8C00"],
[style*=";color:#FF8C00"],
[style*="; color: #FF8C00"],
[style*="; color:#FF8C00"],
[style^="color: #ff8c00"],
[style^="color:#ff8c00"],
[style*=";color: #ff8c00"],
[style*=";color:#ff8c00"],
[style*="; color: #ff8c00"],
[style*="; color:#ff8c00"],
[style^="color: orange"],
[style^="color:orange"],
[style*=";color: orange"],
[style*=";color:orange"],
[style*="; color: orange"],
[style*="; color:orange"],
[style^="color: darkorange"],
[style^="color:darkorange"],
[style*=";color: darkorange"],
[style*=";color:darkorange"],
[style*="; color: darkorange"],
[style*="; color:darkorange"] {
    color: #FFB057 !important;
}

/* Aquila */
[style^="color: blue"],
[style^="color:blue"],
[style*=";color: blue"],
[style*=";color:blue"],
[style*="; color: blue"],
[style*="; color:blue"] {
    color: #7AB0FF !important;
}

/* Ade */
[style^="color: purple"],
[style^="color:purple"],
[style*=";color: purple"],
[style*=";color:purple"],
[style*="; color: purple"],
[style*="; color:purple"] {
    color: #C79CF2 !important;
}

/* Bastione */
[style^="color: brown"],
[style^="color:brown"],
[style*=";color: brown"],
[style*=";color:brown"],
[style*="; color: brown"],
[style*="; color:brown"] {
    color: #E0A074 !important;
}

/* Pericolo */
[style^="color: red"],
[style^="color:red"],
[style*=";color: red"],
[style*=";color:red"],
[style*="; color: red"],
[style*="; color:red"] {
    color: #FF8080 !important;
}

/* Valchiria */
[style^="color: darkcyan"],
[style^="color:darkcyan"],
[style*=";color: darkcyan"],
[style*=";color:darkcyan"],
[style*="; color: darkcyan"],
[style*="; color:darkcyan"] {
    color: #45D6D6 !important;
}

/* Valore */
[style^="color: #b8860b"],
[style^="color:#b8860b"],
[style*=";color: #b8860b"],
[style*=";color:#b8860b"],
[style*="; color: #b8860b"],
[style*="; color:#b8860b"],
[style^="color: #B8860B"],
[style^="color:#B8860B"],
[style*=";color: #B8860B"],
[style*=";color:#B8860B"],
[style*="; color: #B8860B"],
[style*="; color:#B8860B"] {
    color: #E8BF4E !important;
}

/* gold */
[style^="color: #d4af37"],
[style^="color:#d4af37"],
[style*=";color: #d4af37"],
[style*=";color:#d4af37"],
[style*="; color: #d4af37"],
[style*="; color:#d4af37"],
[style^="color: #D4AF37"],
[style^="color:#D4AF37"],
[style*=";color: #D4AF37"],
[style*=";color:#D4AF37"],
[style*="; color: #D4AF37"],
[style*="; color:#D4AF37"] {
    color: #F2D777 !important;
}

/* silver */
[style^="color: #c0c0c0"],
[style^="color:#c0c0c0"],
[style*=";color: #c0c0c0"],
[style*=";color:#c0c0c0"],
[style*="; color: #c0c0c0"],
[style*="; color:#c0c0c0"],
[style^="color: #C0C0C0"],
[style^="color:#C0C0C0"],
[style*=";color: #C0C0C0"],
[style*=";color:#C0C0C0"],
[style*="; color: #C0C0C0"],
[style*="; color:#C0C0C0"] {
    color: #DCDCDC !important;
}

/* bronze */
[style^="color: #cd7f32"],
[style^="color:#cd7f32"],
[style*=";color: #cd7f32"],
[style*=";color:#cd7f32"],
[style*="; color: #cd7f32"],
[style*="; color:#cd7f32"],
[style^="color: #CD7F32"],
[style^="color:#CD7F32"],
[style*=";color: #CD7F32"],
[style*=";color:#CD7F32"],
[style*="; color: #CD7F32"],
[style*="; color:#CD7F32"] {
    color: #EAA877 !important;
}

/* body cells: transparent over the glass, hairline separators only */
table td, table th {
    border: 0 !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.07) !important;
    padding: 10px 12px;
}

table tr:last-child td { border-bottom: 0 !important; }
table tbody tr:hover td { background-color: rgba(255, 255, 255, 0.045); }

/* Giocato Con / Giocato Contro matrices (scores.html).
   Every cell in these is an opaque heat-map swatch, so the glass blur behind
   them buys nothing - and on a ~1200px-tall element it is expensive enough to
   drop frames while scrolling. Opt them out of the backdrop filter. */
#giocatoTable, #giocatoCONTROTable {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: transparent;
    border-collapse: separate !important;
    border-spacing: 0;
    width: 100%;
    text-align: center;
}

#giocatoTable th, #giocatoTable td,
#giocatoCONTROTable th, #giocatoCONTROTable td {
    border: 1px solid rgba(255, 255, 255, 0.07) !important;
    padding: 5px;
    background-color: rgba(255, 255, 255, 0.02);
    color: var(--ink);
}

#giocatoTable .header-special,
#giocatoCONTROTable .header-special { background-color: rgba(0, 184, 28, 0.18); color: var(--ink); }
#giocatoTable .header-normal,
#giocatoCONTROTable .header-normal { background-color: var(--glass-strong); color: var(--ink); }

/* heat-map cells: these encode data, so hues stay - lifted for contrast.
   Both matrices, not just the first: js/tables_call.js builds Giocato Con and
   Giocato Contro with the same class names, but these rules named only
   #giocatoTable, so the second table came out as 870 identical grey cells —
   every class applied, none of them meaning anything. */
#giocatoTable .value-x,
#giocatoCONTROTable .value-x { background-color: rgba(255, 255, 255, 0.02); color: var(--ink-muted); }
#giocatoTable .value-0,
#giocatoCONTROTable .value-0 { background-color: #1d3d59; color: #eaf3ff; }
#giocatoTable .value-1-9,
#giocatoCONTROTable .value-1-9 { background-color: #1d4527; color: #e8ffee; }
#giocatoTable .value-5-10,
#giocatoCONTROTable .value-5-10 { background-color: #59431c; color: #fff4e2; }
#giocatoTable .value-11plus,
#giocatoCONTROTable .value-11plus { background-color: #5c1d1d; color: #ffeaea; }
#giocatoTable .value-21plus,
#giocatoCONTROTable .value-21plus { background-color: #8f1717; color: #ffffff; }

#giocatoTable th,
#giocatoCONTROTable th {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    padding: 5px;
    white-space: nowrap;
}

#giocatoTable .vertical-text,
#giocatoCONTROTable .vertical-text {
    writing-mode: vertical-rl;
    transform: rotate(0deg);
    white-space: nowrap;
}

/* ---------- Accesso Awards matrix (#new-guild-table, scores.html) ----------
   js/tables_call.js builds this table and tags 226 of its cells — value-green,
   value-yellow, the guild abbreviations, one class per player — and until now
   not one of those class names existed in this stylesheet, so the whole table
   rendered flat. The script was never the problem: the rebrand that replaced
   this file at the start dropped the rules its classes refer to.

   Everything is scoped to #new-guild-table on purpose. The guild classes are
   .b, .c, .p, .s — single letters that would be a menace loose in a global
   stylesheet.

   Colours are not invented. The guild abbreviations take the colour each
   guild already carries in css/main_<guild>.css, and the eight leader names
   take their own guild's, which each guild page states: ade/swine,
   aquila/baudo, bastione/copter, cobra/colt, pericolo/puffo, sciabola/karmic,
   valchiria/drius, valore/noble. */

#new-guild-table {
    border-collapse: separate !important;
    border-spacing: 0;
    width: 100%;
    text-align: center;
}

#new-guild-table th,
#new-guild-table td {
    border: 1px solid rgba(255, 255, 255, 0.07) !important;
    padding: 5px 7px;
    background-color: rgba(255, 255, 255, 0.02);
    color: var(--ink);
    white-space: nowrap;
}

#new-guild-table thead th {
    font-weight: 600;
}

/* Met the threshold / one short of it. Same green as .header-special above, so
   the two matrices read as one family. */
#new-guild-table .value-green {
    background-color: rgba(0, 184, 28, 0.20);
    color: #7BEF92;
}

#new-guild-table .value-yellow {
    background-color: rgba(226, 163, 102, 0.20);
    color: #F3C48E;
}

/* The guild abbreviations, each in its own guild's colour. These land on the
   header cells, and `table thead th` further up this file pins every header's
   colour and background with !important — part of the rebrand's contract for
   flattening the legacy inline styling. Without matching that weight these
   rules apply and lose, which is exactly how they looked: classes present,
   headers still plain glass.

   The backgrounds are opaque hex rather than a translucent tint, and that is
   a contrast decision. A tint composites over whatever is behind it, and these
   cells sit on the table's glass panels, not on the page — measured on the
   real page a 0.16 tint put five of the eight at 3.6-4.4:1 even though the
   arithmetic against the page's black said 4.45+. Each value below is that
   guild's colour at 10% over the page black, baked flat, so what the cell
   paints no longer depends on what is underneath it. Worst is now 4.78:1. */
#new-guild-table .ad { color: #887BB8 !important; background-color: #17151D !important; }
#new-guild-table .aq { color: #3C89C6 !important; background-color: #0F171F !important; }
#new-guild-table .b  { color: #A17D52 !important; background-color: #191613 !important; }
#new-guild-table .c  { color: #6F8D48 !important; background-color: #141712 !important; }
#new-guild-table .p  { color: #C16A6A !important; background-color: #1C1415 !important; }
#new-guild-table .s  { color: #E2A366 !important; background-color: #201915 !important; }
#new-guild-table .vk { color: #94DDDF !important; background-color: #181F21 !important; }
#new-guild-table .va { color: #BFA451 !important; background-color: #1C1913 !important; }

/* The eight leaders, in the colour of the guild they lead. Only the first and
   last column carry these — the script puts the player's name at both ends of
   every row so a wide table stays readable without scrolling back. */
#new-guild-table .swine  { color: #887BB8; }
#new-guild-table .baudo  { color: #3C89C6; }
#new-guild-table .copter { color: #A17D52; }
#new-guild-table .colt   { color: #6F8D48; }
#new-guild-table .puffo  { color: #C16A6A; }
#new-guild-table .karmic { color: #E2A366; }
#new-guild-table .drius  { color: #94DDDF; }
#new-guild-table .noble  { color: #BFA451; }

#new-guild-table .swine,
#new-guild-table .baudo,
#new-guild-table .copter,
#new-guild-table .colt,
#new-guild-table .puffo,
#new-guild-table .karmic,
#new-guild-table .drius,
#new-guild-table .noble {
    font-weight: 600;
    /* Opaque for the same reason as the abbreviations above: a white tint here
       rides on the glass behind the table and drags the darker guild colours
       under 4.5:1. Flat, the worst of the eight is 4.58:1. */
    background-color: #1A1A1C;
    text-align: left;
}

/* Everyone who plays without a guild. */
#new-guild-table .mercenario {
    color: var(--ink);
    text-align: left;
}

/* The four who have not played a war yet — every figure on their row is
   blank, so the name is dimmed rather than sitting there as loud as the rest. */
#new-guild-table .socrem,
#new-guild-table .bibobio,
#new-guild-table .trimrex,
#new-guild-table .deadrick {
    color: var(--ink-muted);
    text-align: left;
}

#giocatoCONTROTable {
    border-collapse: separate !important;
    border-spacing: 0;
    width: 100%;
    text-align: center;
}

/* Wide data tables stay reachable on small screens through .table-scroll —
   see the rule next to it. This used to be `table { display: block }`, which
   was the reason tables looked shrunk on a phone: as a block the table honours
   its inline width (the legacy markup sets 45%, 50%, 80%), so a table needing
   589px was drawn 168px wide inside a 374px column and scrolled inside itself,
   while the wrapper that should have scrolled sat there unused. */

/* ---------- shop (legacy, present in CSS contract even if unused) ---------- */
#webshop > .shop { display: flex; flex-wrap: wrap; }

.shop > .shop-item {
    position: relative;
    width: 27%;
    background-color: var(--surface);
    border-radius: 14px;
    margin: 2% 1%;
    padding: 2%;
}

.shop > .shop-item > .price-tag {
    background-color: var(--secundary-color);
    position: absolute;
    right: 10px;
    top: -40px;
    z-index: 2;
    height: 60px;
    width: 48px;
    padding: 10px;
    border-radius: 8px;
}

.shop > .shop-item > .price-tag > .amount { position: absolute; bottom: 10px; }

.shop > .shop-item figure {
    max-width: 250px;
    margin: 0 auto;
    transition: transform 0.2s;
    z-index: 1;
    cursor: pointer;
}

.shop > .shop-item figure:hover { transform: scale(1.15); }

.shop > .shop-item > figure > img { width: 100%; }

.shop > .shop-item > .description {
    position: relative;
    font-style: italic;
    text-align: center;
    margin-top: 20px;
    min-height: 75px;
    z-index: 2;
    color: var(--ink-muted);
}

.shop > .selected-shop-item {
    width: 100%; height: 100vh;
    background-color: rgba(0, 0, 0, 0.7);
    position: fixed; top: 0; left: 0;
    z-index: 4;
    transition: all 0.2s;
}

.shop > .selected-shop-item > .content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    max-width: 75%;
    max-height: 60vh;
    margin: 20vh auto;
    background-color: var(--surface);
    border-radius: 18px;
    padding: 24px;
    box-sizing: border-box;
    color: var(--ink);
    position: relative;
}

.shop > .selected-shop-item > .content > .exit-button {
    position: absolute;
    right: 0px; top: 0;
    cursor: pointer;
    background-color: var(--surface-2);
    text-align: center;
    padding: 10px;
    width: 40px;
    margin: 0;
    border: none;
    border-radius: 0 18px 0 12px;
}

.shop > .selected-shop-item > .content > figure { margin: 0 auto; }
.shop > .selected-shop-item > .content > figure > img { width: 350px; }

.shop > .selected-shop-item > .content > .details {
    display: grid;
    grid-template-rows: 1.4fr 1fr;
}

.shop > .selected-shop-item > .content > .details .item-name { margin: 0.2em 0; }

.shop > .selected-shop-item > .content > .details input {
    padding: 2%;
    width: 100%;
    border: 1px solid var(--hair);
    background: var(--surface-2);
    color: var(--ink);
    font-size: 1.2em;
    display: block;
    margin-top: 10%;
    box-sizing: border-box;
    margin-bottom: 2em;
    border-radius: 8px;
}

.order-form {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 50px;
}

.order-form article ul { list-style: none; margin: 0; padding: 0; }

.order-form article ul li:before {
    content: '\2714';
    color: var(--primary-color);
    margin-right: 1em;
}

.order-form > form .field { display: block; margin: 10px 0; }
.order-form > form label { display: block; margin: 0.8em 0; }

.order-form > form input {
    width: 100%;
    padding: 16px 12px;
    border-radius: 8px;
    border: 1px solid var(--hair);
    background: var(--surface);
    color: var(--ink);
    box-sizing: border-box;
}

footer {
    text-align: center;
    margin: 60px 0 0;
    background-color: var(--surface-2);
    border-top: 1px solid var(--hair);
    font-size: 0.8em;
    line-height: 1.6;
    color: var(--ink-muted);
    padding: 36px 20px 28px;
}

footer a { color: var(--primary-color); }
footer a:hover { text-decoration: underline; }

/* ---------- responsive base kept from original ---------- */
/* The rail used to be a fixed-height stage (50vh / 40vh) with absolutely
   positioned slides. It is now a scroll-snap peek rail whose cards carry
   their own 16/10 aspect-ratio, and a viewport height on the rail simply
   stretched every card past that ratio — 284x348 instead of 284x177 on a
   phone. The rail takes its height from the cards. */
@media (max-width: 600px) {
    .episode > img { max-height: 100%; }
}

@media (max-width: 1024px) {
    .episode > figcaption { font-size: 0.9em; padding: 8px; }
}

@media (max-width: 600px) {
    .episode > figcaption { font-size: 0.8em; padding: 6px; }
}

@media (min-width: 761px) {
    /* 48px total including the hairline, as on the home page — without an
       explicit height the bar took the row's 48px and added the border on
       top, coming out a pixel taller. Scoped to desktop: on mobile this
       header also holds the burger bar, which is taller. */
    #main-header {
        height: 48px;
        transition: background-color 0.2s;
    }

    #main-header > nav,
    #main-header > nav > ul {
        height: 100%;
        min-height: 0;
    }
}

@media (hover: hover) {
    .season > .episodes > .episode > img:hover,
    .character-profile > .character > figure > img:hover,
    .shop > .shop-item figure:hover {
        transform: none !important;
        transition: none !important;
    }
}

/* ---------- lightbox ---------- */
.zoomable { cursor: zoom-in; }

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

body.lightbox-open { overflow: hidden; }

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 10000;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: clamp(16px, 4vw, 48px);
    background: rgba(0, 0, 0, 0.86);
    backdrop-filter: blur(22px) saturate(140%);
    -webkit-backdrop-filter: blur(22px) saturate(140%);
    animation: lightbox-in 0.18s ease-out;
}

.lightbox[hidden] { display: none; }

.lightbox > img {
    max-width: 100%;
    max-height: calc(100vh - 150px);
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: var(--r);
    box-shadow: var(--shadow-lg);
    cursor: default;
}

.lightbox-cap {
    margin: 0;
    max-width: 70ch;
    text-align: center;
    font-size: 0.95em;
    line-height: 1.45;
    color: var(--ink-muted);
}

.lightbox-close {
    position: absolute;
    top: clamp(12px, 3vw, 26px);
    right: clamp(12px, 3vw, 26px);
    width: 42px;
    height: 42px;
    padding: 0;
    margin: 0;
    border-radius: 999px;
    border: 1px solid var(--glass-hair);
    background: var(--glass-strong);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    color: var(--ink);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}

.lightbox-close:hover { background: rgba(255, 255, 255, 0.16); }

@keyframes lightbox-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .lightbox { animation: none; }
}
