:root{--bg:#0D0D0D;--surface:#1A1A1A;--raised:#252525;--text:#FFFFFF;--muted:#a3a3a3;--accent:#FF4081;--accent-text:#FFFFFF;--border:#2D2D2D;--border-accent:#00E676;--cta-bg:#00E676;--cta-text:#000000;--cta-hover-bg:#00C853;--radius:12px;--bw:1px;--zebra:rgba(255,255,255,.028);--shadow:rgba(0,0,0,.45);--shadow-card:0 4px 12px rgba(0, 0, 0, 0.5);--shadow-btn:0 4px 12px rgba(0, 230, 118, 0.3);--font-h:'Montserrat', system-ui, sans-serif;--font-b:'Inter', system-ui, sans-serif;--fw-h:800;--fw-btn:600;--gutter:18px;--gap:12px;--header-h:57px}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-b);font-size:17px;line-height:1.65;overflow-wrap:break-word}
/* One gutter, owned here. Everything that also carries `.wrap` must set its
   vertical padding with `padding-block`, never the `padding` shorthand — the
   shorthand resets padding-left/right to 0 at equal specificity, and `.hero`
   and `.content` did exactly that. The result was a page whose headline, body
   copy, tables and CTA ran edge to edge while the games, FAQ and review
   sections were inset by 18px. */
.wrap{width:100%;max-width:820px;margin:0 auto;padding-inline:var(--gutter)}
a{color:var(--accent);text-decoration:none}
@media(hover:hover){a:hover{text-decoration:underline}}
h1,h2,h3,h4{font-family:var(--font-h);font-weight:var(--fw-h);line-height:1.22;letter-spacing:-.015em;margin:2em 0 .6em}
h1{font-size:clamp(1.75rem,5.2vw,2.6rem);margin-top:0}
h2{font-size:clamp(1.35rem,3.6vw,1.85rem);padding-top:.5em}
h3{font-size:clamp(1.12rem,2.8vw,1.35rem)}
p,ul,ol{margin:0 0 1.1em}
ul,ol{padding-left:1.25em}
li{margin:.35em 0}
hr{border:0;border-top:1px solid var(--border);margin:2.5em 0}
/* Header — brand and CTA on one row, nav on its own row beneath. Nine in ten
   visitors are on a phone, and at 390px a single row could not hold all three:
   a 200px logo left the nav clipped mid-word and pushed the CTA into a
   two-line block that overflowed the header. From 760px up the nav folds back
   between them. */
.site-header{position:sticky;top:0;z-index:20;background:color-mix(in srgb,var(--bg) 88%,transparent);backdrop-filter:saturate(1.4) blur(10px);border-bottom:1px solid var(--border)}
.site-header .wrap{display:flex;align-items:center;gap:10px;min-height:56px}
.brand{font-family:var(--font-h);font-weight:700;font-size:1.12rem;color:var(--text);letter-spacing:-.02em;margin-right:auto;min-width:0;display:inline-flex;align-items:center;min-height:44px}
.brand:hover{text-decoration:none}
.header-cta{flex:none;order:3}
.header-cta .cta{white-space:nowrap}
/* A logo replaces the wordmark, so the link becomes a box for the image. The
   height cap is what keeps a tall logo from stretching the header; the vw cap
   is what stops a wide one from taking the whole phone header. */
.brand-logo{display:inline-flex;align-items:center;line-height:0;max-width:100%}
.brand-logo img{max-height:32px;width:auto;height:auto;max-width:min(180px,44vw);object-fit:contain}
@media(min-width:760px){
 .site-header .wrap{gap:12px;min-height:58px}
 .brand-logo img{max-height:34px;max-width:200px}
}
/* Banner: full content width, its own aspect box so nothing shifts while it
   loads. */
.banner{margin:18px auto 0}
.banner img{width:100%;height:auto;display:block;border-radius:var(--radius);border:var(--bw) solid var(--border);box-shadow:var(--shadow-card)}
/* Nav — a disclosure panel on a phone, inline from 760px up.
   A second header row cost 52px of every screen for links the footer already
   carries; a horizontally scrolling one clipped "Politique de confidentialité"
   with no affordance that anything was hidden. The panel anchors to
   .site-header, which is `position:sticky` and therefore a containing block.
   44px is the tap-target floor, here and in the footer and the TOC. */
.nav-wrap{order:2;flex:none}
.nav-wrap > summary{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:center;width:44px;height:44px;margin-right:-8px;border-radius:var(--radius)}
.nav-wrap > summary::-webkit-details-marker{display:none}
.nav-burger,.nav-burger::before,.nav-burger::after{display:block;width:19px;height:2px;background:var(--text);border-radius:2px}
.nav-burger{position:relative}
.nav-burger::before,.nav-burger::after{content:"";position:absolute;left:0}
.nav-burger::before{top:-6px}
.nav-burger::after{top:6px}
.nav-wrap[open] > summary .nav-burger{background:transparent}
.nav-wrap[open] > summary .nav-burger::before{top:0;transform:rotate(45deg)}
.nav-wrap[open] > summary .nav-burger::after{top:0;transform:rotate(-45deg)}
.nav{display:flex;flex-direction:column;position:absolute;left:0;right:0;top:100%;background:var(--bg);border-bottom:1px solid var(--border);box-shadow:var(--shadow-card);padding:4px 18px 10px}
.nav a{color:var(--text);font-size:1rem;display:flex;align-items:center;min-height:48px;border-bottom:1px solid var(--border)}
.nav a:last-child{border-bottom:0}
@media(min-width:760px){
 /* The panel is simply always shown here — no toggle state to get stuck in.
    Two mechanisms because browsers changed one: current engines hide a closed
    <details> with `content-visibility` on `::details-content`, which no
    `display` on the child can override, while older ones use the UA rule
    `details:not([open]) > *:not(summary){display:none}`, which any author
    declaration outranks. Set both or desktop loses its nav entirely. */
 .nav-wrap{order:1;margin-left:auto}
 .nav-wrap::details-content{content-visibility:visible;block-size:auto}
 .nav-wrap > summary{display:none}
 .nav{display:flex;flex-direction:row;position:static;gap:14px;padding:0;background:none;border:0;box-shadow:none}
 .nav a{color:var(--muted);font-size:.92rem;white-space:nowrap;min-height:0;border:0;display:inline}
}
/* CTA */
.cta{display:inline-flex;align-items:center;justify-content:center;gap:.5em;background:var(--cta-bg);color:var(--cta-text);font-family:var(--font-h);font-weight:var(--fw-btn);font-size:.95rem;padding:.62em 1.15em;border-radius:var(--radius);border:0;cursor:pointer;text-align:center;box-shadow:var(--shadow-btn);transition:transform .12s ease,background-color .12s ease,filter .12s ease}
/* Touch has no hover: without this guard a tapped CTA or tile keeps its hover
   state until the next tap lands somewhere else. */
@media(hover:hover){.cta:hover{background:var(--cta-hover-bg);filter:brightness(1.04);text-decoration:none}}
.cta:active{transform:translateY(1px)}
.cta-lg{font-size:1.06rem;padding:.8em 1.7em;width:100%}
@media(min-width:620px){.cta-lg{width:auto}}
/* 44px is the tap-target floor; the header CTA is the one control on the page
   that must never be a near-miss. Inline links inside prose are exempt — a
   44px-tall word in a sentence is worse than the miss it prevents. */
.cta-sm{font-size:.86rem;padding:.5em .9em;min-height:44px}
/* Hero */
.hero{padding-block:34px 6px}
.hero .kicker{display:inline-block;font-size:.74rem;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);border:1px solid var(--border);border-radius:999px;padding:.32em .85em;margin-bottom:14px}
.hero .lede{color:var(--muted);font-size:1.05rem;margin:.2em 0 1.4em}
.hero-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin-bottom:8px}
.hero-note{color:var(--muted);font-size:.82rem}
@media(min-width:600px){:root{--gutter:24px}}
/* Body */
.content{padding-block:8px 40px}
:where(h2,h3,.section,[id]){scroll-margin-top:calc(var(--header-h) + 16px)}
.table-scroll{overflow-x:auto;margin:0 0 1.4em;border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--surface)}
table{border-collapse:collapse;width:100%;font-size:.94rem;min-width:min(100%,460px)}
th,td{padding:.66em .85em;text-align:left;border-bottom:1px solid var(--border);vertical-align:top}
/* Wrapping headers beat a sideways scroll on a phone: a two-word label costs
   one extra line, where `nowrap` can push a three-column table 50px past the
   viewport and hide a column behind a gesture nobody makes. */
th{font-family:var(--font-h);font-weight:650;background:var(--raised)}
@media(min-width:640px){th{white-space:nowrap}}
tbody tr:nth-child(even){background:var(--zebra)}
tbody tr:last-child td{border-bottom:0}
/* TOC — collapsed, like pbn-template's. A twenty-entry list at a 44px tap
   target is 880px of scrolling between the hero and the first paragraph, which
   on a phone is the whole article pushed off the screen. */
.toc{background:var(--surface);border:var(--bw) solid var(--border);border-radius:var(--radius);padding:4px 18px;margin:0 0 2em;box-shadow:var(--shadow-card)}
.toc > summary{cursor:pointer;list-style:none;display:flex;align-items:center;min-height:48px;font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.toc > summary::-webkit-details-marker{display:none}
.toc > summary::after{content:"+";margin-left:auto;color:var(--border-accent);font-size:1.5em;line-height:1;letter-spacing:0}
.toc[open] > summary::after{content:"–"}
.toc ol{list-style:none;padding:0 0 12px;margin:0;counter-reset:toc}
.toc li.d2{counter-increment:toc}
.toc li.d3{padding-left:1.15em;font-size:.94rem}
.toc a{color:var(--text);display:flex;align-items:center;min-height:44px}
.toc a::before{content:counter(toc) ". ";color:var(--muted);margin-right:.4em}
.toc li.d3 a::before{content:"— ";}
@media(min-width:760px){.toc a{min-height:0;display:inline}.toc li{margin:.3em 0}}
/* 1400px, not 1080. The rail floats 278px out of an 820px centred column, so
   its right edge lands at viewport/2 + 688 — which is past the viewport on
   anything narrower than ~1376px. Between 1080 and 1376 that meant a sidebar
   hanging off the page and a horizontal scrollbar on every `railed` and
   `editorial` site, at 1280px, the commonest desktop width there is. Below
   this breakpoint the TOC keeps its ordinary in-flow styling, which is fine.
   Found by the visual check, which is also why VIEWPORTS carries a 1440px
   width — 1280 alone would never exercise this branch again. */
@media(min-width:1400px){
 body.toc-sidebar .content{position:relative}
 body.toc-sidebar .toc{position:sticky;top:74px;float:right;width:250px;margin:0 -278px 1.5em 28px;font-size:.93rem}
 /* A sidebar that has to be opened is not a sidebar. Both mechanisms, for the
    same reason as the nav above. */
 body.toc-sidebar .toc::details-content{content-visibility:visible;block-size:auto}
 body.toc-sidebar .toc > ol{display:block}
 body.toc-sidebar .toc > summary{pointer-events:none}
 body.toc-sidebar .toc > summary::after{display:none}
}
/* Sections */
.section{padding-block:26px;border-top:1px solid var(--border)}
.section > h2{margin-top:0}
/* FAQ */
.faq-item{border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--surface);margin-bottom:var(--gap);overflow:hidden;box-shadow:var(--shadow-card)}
.faq-item summary{cursor:pointer;padding:.9em 1.05em;font-family:var(--font-h);font-weight:600;list-style:none;display:flex;gap:.7em;align-items:flex-start}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";margin-left:auto;color:var(--border-accent);font-size:1.3em;line-height:1;flex:none}
.faq-item[open] summary::after{content:"–"}
.faq-item .answer{padding:0 1.05em 1em;color:var(--muted)}
/* The `list` variants are one panel of flat rows, not N borderless rows on the
   page background. Structurally still distinct from the accordion — one card
   instead of many — but it carries the same border, radius and surface as
   every other block, instead of reading as the one unstyled section. */
body.faq-list .faq-items{border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-card);padding:0 16px;overflow:hidden}
body.faq-list .faq-item{border:0;border-radius:0;border-bottom:1px solid var(--border);background:none;box-shadow:none;margin-bottom:0}
body.faq-list .faq-item:last-child{border-bottom:0}
body.faq-list .faq-item summary{padding-left:0;padding-right:0}
body.faq-list .faq-item .answer{padding-left:0;padding-right:0}
/* Reviews */
.stars{color:var(--accent);letter-spacing:.08em}
.reviews{display:grid;gap:var(--gap)}
@media(min-width:700px){body.reviews-cards .reviews{grid-template-columns:1fr 1fr}}
.review{background:var(--surface);border:var(--bw) solid var(--border);border-radius:var(--radius);padding:14px 16px;box-shadow:var(--shadow-card)}
.review .head{display:flex;align-items:center;gap:8px;margin-bottom:.5em}
.review .who{font-family:var(--font-h);font-weight:650;font-size:.94rem}
.review .stars{font-size:.86rem;margin-left:auto}
.review p{margin:0;color:var(--muted);font-size:.95rem}
body.reviews-list .reviews{gap:0;border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-card);padding:0 16px;overflow:hidden}
body.reviews-list .review{border:0;border-bottom:1px solid var(--border);border-radius:0;background:none;box-shadow:none;padding:14px 0}
body.reviews-list .review:last-child{border-bottom:0}
body.reviews-quotes .review{border:0;border-left:3px solid var(--border-accent);border-radius:0;background:none;padding:4px 0 4px 16px}
/* Callout */
.callout{background:var(--surface);border:var(--bw) solid var(--border);border-left:3px solid var(--border-accent);border-radius:var(--radius);padding:18px;margin:2em 0;display:flex;flex-direction:column;gap:12px;box-shadow:var(--shadow-card)}
.callout .headline{font-family:var(--font-h);font-weight:650;font-size:1.06rem}
/* Tile grids (games / providers) */
.grid-section > h2{margin-bottom:.9em}
.tile-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--gap)}
@media(min-width:700px){.tile-grid.games{grid-template-columns:repeat(4,1fr)}.tile-grid.providers{grid-template-columns:repeat(4,1fr)}}
.tile{background:var(--surface);border:var(--bw) solid var(--border);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow-card);cursor:pointer;transition:transform .12s ease,border-color .12s ease}
/* The tiles are keyboard-activatable (role=button + tabindex), so they need a
   visible focus ring — the pointer cursor and hover lift say nothing to
   someone tabbing through the grid. */
.tile:focus-visible{outline:2px solid var(--cta-bg);outline-offset:2px}
@media(hover:hover){.tile:hover{transform:translateY(-2px);border-color:var(--border-accent)}}
.tile-media{aspect-ratio:1/1;display:flex;align-items:center;justify-content:center;background:var(--raised);overflow:hidden}
/* Providers fill their tile exactly as games fill theirs. Every logo in the
   manifest is 800x450 and the media box is already 16/9, so `cover` covers it
   with nothing cropped — and the logo's own background plate becomes the tile
   media rather than sitting inside it as a second rectangle. The padded,
   letterboxed version needed a nested radius to stop looking like a sticker;
   this needs nothing, because there is no longer anything nested. */
.tile-grid.providers .tile-media{aspect-ratio:16/9}
.tile-media img{width:100%;height:100%;object-fit:cover;display:block}
.tile-body{padding:9px 11px;display:flex;flex-direction:column;gap:2px;min-width:0}
/* Two lines on a phone, one from 700px up. At 2-up on a 390px screen a tile is
   ~165px wide, and "Riptide Pirates 2 Kraken Riches" truncated to one line is
   not a game anyone recognises. */
.tile-name{font-family:var(--font-h);font-weight:600;font-size:.9rem;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2}
.tile-sub{color:var(--muted);font-size:.78rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(min-width:700px){.tile-name{display:block;-webkit-line-clamp:none;line-clamp:none;text-overflow:ellipsis;white-space:nowrap}}
/* Banner block: the offer line over a game logo */
/* No border. Everywhere else the hairline separates `--surface` from `--bg`,
   two tones close enough to need it. This block is filled with a darkened
   image, so the same `--border` grey reads as a bright outline against it —
   and along a 12px arc the 1px stroke is spread over several pixels of
   anti-aliasing, which is what turned the corners into bright wedges. The
   image is its own edge. */
.banner-block{position:relative;margin-top:18px;border-radius:var(--radius);overflow:hidden;min-height:150px;display:flex;align-items:center;justify-content:center;text-align:center;cursor:pointer;box-shadow:var(--shadow-card)}
/* Oversized on purpose. `blur()` samples past the image's own edge, so a layer
   sized exactly to the box fades toward transparent all the way round — which
   reads as a bright rim, worst at the corners where two fades meet. Growing it
   by twice the blur radius puts that rim outside the parent's rounded clip. */
.banner-block-bg{position:absolute;inset:-6px;width:calc(100% + 12px);height:calc(100% + 12px);object-fit:cover;filter:blur(2px) saturate(1.1);opacity:.55}
.banner-block::after{content:"";position:absolute;inset:0;background:linear-gradient(to bottom,color-mix(in srgb,var(--bg) 45%,transparent),color-mix(in srgb,var(--bg) 82%,transparent))}
.banner-block-body{position:relative;z-index:1;padding:26px 20px;display:flex;flex-direction:column;align-items:center;gap:14px}
.banner-block-text{font-family:var(--font-h);font-weight:var(--fw-h);font-size:clamp(1.1rem,3.4vw,1.5rem);margin:0;line-height:1.3;text-shadow:0 1px 3px var(--shadow)}
/* Footer */
.site-footer{border-top:1px solid var(--border);margin-top:20px;padding:26px 0 40px;color:var(--muted);font-size:.87rem}
.site-footer .disclaimer{margin-bottom:1em}
.site-footer .foot-nav{display:flex;flex-wrap:wrap;gap:0 16px;margin-bottom:1em}
.site-footer .foot-nav a{display:inline-flex;align-items:center;min-height:44px}
@media(min-width:760px){.site-footer .foot-nav{gap:14px}.site-footer .foot-nav a{min-height:0}}
.age{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border-radius:999px;border:1.5px solid var(--muted);font-size:.7rem;font-weight:700;flex:none}
.foot-top{display:flex;align-items:center;gap:14px;margin-bottom:1em;flex-wrap:wrap}
/* ── Component variants (src/variants.js) ──────────────────────────────────
   Each of these is a separate PHP partial, so the rules below style DIFFERENT
   markup rather than restyling one shared tree. Mobile-first throughout: every
   multi-column rule is inside a min-width query, so all variants collapse to
   the same single column on a phone. */
/* hero: split — copy beside an action card, one column under 760px. */
.hero-split .hero-card{margin-top:1.1em;background:var(--surface);border:var(--bw) solid var(--border);border-radius:var(--radius);padding:16px;display:flex;flex-direction:column;gap:10px;box-shadow:var(--shadow-card)}
.hero-split .hero-card .hero-note{margin:0}
/* minmax(0,1fr), not 1fr: a grid column's implicit minimum is min-content, so
   a long unbreakable word in the h1 pushes the copy column wider than its
   share and the whole page scrolls sideways at desktop. Caught by the visual
   check, not by looking — the hero looked fine, the scrollbar was 200px
   further down the page. */
@media(min-width:760px){.hero-split{display:grid;grid-template-columns:minmax(0,1fr) minmax(240px,320px);gap:calc(var(--gap) * 1.5);align-items:start}.hero-split .hero-copy{min-width:0}.hero-split .hero-card{margin-top:0}}
/* hero: panel — the whole hero inside one surface, note promoted above. */
.hero-panel .hero-panel-inner{background:var(--surface);border:var(--bw) solid var(--border);border-radius:var(--radius);padding:18px 18px 20px;box-shadow:var(--shadow-card)}
.hero-panel .hero-note-top{margin:0 0 .7em;padding-bottom:.7em;border-bottom:var(--bw) solid var(--border);color:var(--muted);font-size:.82rem}
.hero-panel .hero-actions{margin-top:1.1em}
/* footer: columns — seals beside a stacked nav, legal block beneath. */
.footer-columns .foot-band{display:flex;flex-direction:column;gap:1.2em;margin-bottom:1.2em}
.footer-columns .foot-brand{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.footer-columns .foot-nav-stack{display:flex;flex-direction:column;gap:0;margin:0}
@media(min-width:760px){.footer-columns .foot-band{flex-direction:row;justify-content:space-between;align-items:flex-start}.footer-columns .foot-nav-stack{align-items:flex-end}}
.footer-columns .foot-legal{border-top:var(--bw) solid var(--border);padding-top:1em}
/* Locale switcher — a <details> disclosure, never a <button>: the click
   handler's hook is the button element, so one here would open the casino.
   Closed by default; the list is a plain block, not an overlay, because an
   absolutely-positioned dropdown at the bottom of a page opens off-screen on a
   phone. */
/* inline-block so the whole control follows its container's alignment. As a
   block it spanned the footer's full width, which put the open panel hard
   against the left edge while the summary above it centred with everything
   else — correct CSS, obviously wrong to look at. Shrink-to-fit means the
   centred footer centres it and the left-aligned ones do not, with no
   per-variant rule to keep in sync. */
.locale-switcher{display:inline-block;margin:0 0 1em;text-align:left}
.locale-switcher>summary{display:inline-flex;align-items:center;gap:8px;min-height:44px;cursor:pointer;list-style:none;color:var(--muted)}
.locale-switcher>summary::-webkit-details-marker{display:none}
.locale-switcher>summary::after{content:"";width:6px;height:6px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg);margin-top:-3px}
.locale-switcher[open]>summary::after{transform:rotate(-135deg);margin-top:3px}
.locale-switcher ul{list-style:none;margin:.4em 0 0;padding:0;display:flex;flex-direction:column;border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--surface);max-height:60vh;overflow-y:auto}
.locale-switcher li+li{border-top:var(--bw) solid var(--border)}
.locale-switcher li a{display:flex;align-items:center;min-height:44px;padding:0 12px}
.locale-switcher a[aria-current]{background:var(--raised);font-weight:600}
@media(min-width:760px){.locale-switcher ul{max-width:260px}}
/* footer: centered — nav first, seals under it, everything centred. */
.footer-centered{text-align:center}
.footer-centered .foot-nav{justify-content:center}
.footer-centered .foot-top{justify-content:center;margin-top:1em}
/* Seals sit at a common optical height rather than a common box: the source
   art has different aspect ratios, so matching widths would make the wide one
   tower over the square one. Height-capped with width:auto keeps the row's
   baseline even. Muted until hovered — they are reassurance, not decoration
   competing with the CTA. */
/* The link is the tap target, not the image. A 26px badge is a 26px target,
   and footer links owe 44px — so the anchor carries the height and the image
   keeps its size inside it. */
.foot-badge-link{display:inline-flex;align-items:center;min-height:44px}
/* Height-driven, width follows the ratio, at every width including a phone.
   Both dimensions are `auto` — the intrinsic width/height attributes carry the
   ratio and the image shrinks to fit `max-height`.

   `max-width` is a blowout backstop, not a styling rule, and **it must stay
   above (widest ratio x max-height) or it silently breaks uniform height**:
   the moment it binds, that badge scales down and stands shorter than the rest
   of the strip. Today the widest is McAfee at 4.98:1, so 26px tall is 129px
   and the 140px cap has room to spare. Add a wider badge and either raise this
   or accept that one badge riding lower than its neighbours.

   `verify-variants` asserts the strip's heights match, so a future badge that
   trips the cap fails a build rather than shipping. */
.foot-badge{height:auto;width:auto;max-height:24px;max-width:140px;opacity:.75;filter:grayscale(1);transition:opacity .15s ease,filter .15s ease}
@media(min-width:760px){.foot-badge{max-height:26px}}
/* Plate art is a finished coloured badge, not line work. It still gets
   desaturated so it sits with the rest of the strip — one full-colour badge
   among four grey ones reads as a mistake — but never brightness(0), which
   on a light palette would flatten a green plate with white text into a solid
   black square. grayscale keeps the plate/text contrast that is baked in. */
.foot-badge-plate{filter:grayscale(1);opacity:.85}
@media(hover:hover){.foot-badge:hover{opacity:1;filter:none}}
@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}