
@font-face { font-family:'Poppins'; font-weight:400; font-style:normal; font-display:swap; src:url('/assets/fonts/Poppins-Regular.woff2') format('woff2'); }
@font-face { font-family:'Poppins'; font-weight:500; font-style:normal; font-display:swap; src:url('/assets/fonts/Poppins-Medium.woff2') format('woff2'); }
@font-face { font-family:'Poppins'; font-weight:700; font-style:normal; font-display:swap; src:url('/assets/fonts/Poppins-Bold.woff2') format('woff2'); }
:root { --fr-red:#EF4135; --fr-blue:#0055A4; --fr-navy:#0A2A57; --fr-gold:#FFC72C; --tube-green:#00782A;
  --paper:#FAFAF8; --ink:#0B0B0C; --grey:#6E6E6E; --card:#FFFFFF; --line:#E7E5E0; }
* { box-sizing: border-box; }
body { margin:0; font-family:'Poppins',-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; background:var(--paper); color:var(--ink); min-height:100vh; }
a { color: inherit; }
.site-header { background:var(--fr-navy); color:#fff; padding: 0.85rem 1rem; position: sticky; top:0; z-index: 50; box-shadow: 0 2px 10px rgba(0,15,88,0.18); }
.site-header-inner { max-width: 1120px; margin: 0 auto; display:grid; grid-template-columns: 1fr auto 1fr; align-items:center; gap: 0.8rem; }
.site-logo { display:flex; align-items:center; gap:0.5rem; text-decoration:none; justify-self:center; }
.site-logo-mark { display:block; flex-shrink:0; height:clamp(40px, 6vw, 60px); width:auto; }
.site-logo-text { font-weight:700; font-size:clamp(1.3rem, 2.3vw, 1.7rem); line-height:1; letter-spacing:-0.01em; white-space:nowrap; }
.site-logo-text .lg1 { color:#fff; }
.site-logo-text .lg2 { color:var(--fr-gold); }
.hamburger-btn { background:rgba(255,255,255,0.14); border:none; color:#fff; width:2.4rem; height:2.4rem; border-radius:8px; display:flex; align-items:center; justify-content:center; cursor:pointer; justify-self:start; }
.hamburger-btn:hover { background:rgba(255,255,255,0.24); }
/* Mirrors the hamburger button exactly (same size/background/shape) but
   sits in the grid's third column with justify-self:end, so it lands on the
   exact opposite side of the header from the hamburger icon, with the logo
   staying centered between the two (site-header-inner's grid is
   1fr/auto/1fr - the hamburger fills col1 start, this fills col3 end, both
   equal-width columns keep the centered logo symmetric either way). Shares
   the *current* URL, which is whatever page/category/membership/discount
   the visitor has actually navigated to - no per-page wiring needed since
   this header markup is shared across every page and reads
   window.location.href at click time. */
.share-btn { background:rgba(255,255,255,0.14); border:none; color:#fff; width:2.4rem; height:2.4rem; border-radius:8px; display:flex; align-items:center; justify-content:center; cursor:pointer; justify-self:end; }
.share-btn:hover { background:rgba(255,255,255,0.24); }
.share-btn svg { width:18px; height:18px; }
/* Small toast confirming the link was copied, for browsers without the
   native share sheet (navigator.share) - most desktop browsers. Fixed to
   the bottom of the viewport so it doesn't shift any page layout, fades in
   on .show and back out a couple seconds later. */
.share-toast { position:fixed; left:50%; bottom:1.4rem; transform:translateX(-50%) translateY(0.4rem); background:var(--fr-navy); color:#fff; font-size:0.85rem; font-weight:700; padding:0.6rem 1.1rem; border-radius:999px; box-shadow:0 4px 14px rgba(0,15,88,0.28); opacity:0; pointer-events:none; transition:opacity 0.2s ease, transform 0.2s ease; z-index:200; }
.share-toast.show { opacity:1; transform:translateX(-50%) translateY(0); }
.search-bar-wrap { max-width:1120px; margin: 0.75rem auto 0; position:relative; }
#searchInput { width:100%; padding:0.7rem 1rem; border-radius:10px; border:none; font-size:1rem; }
.search-results { position:absolute; left:0; right:0; top:100%; background:#fff; border-radius:0 0 10px 10px; box-shadow:0 10px 26px rgba(0,15,88,0.25); z-index:60; overflow:hidden; display:none; max-height:60vh; overflow-y:auto; }
.search-results.open { display:block; }
.search-results a { display:flex; align-items:center; gap:0.6rem; padding:0.6rem 0.9rem; color:var(--ink); text-decoration:none; border-bottom:1px solid var(--line); font-size:0.92rem; }
.search-results a:hover { background:#f2f2ef; }
.search-results .sr-type { margin-left:auto; font-size:0.7rem; color:var(--grey); text-transform:uppercase; letter-spacing:0.04em; }
.drawer-backdrop { position:fixed; inset:0; background:rgba(0,0,0,0.45); z-index:90; display:none; }
.drawer-backdrop.open { display:block; }
.drawer { position:fixed; top:0; left:0; bottom:0; width:280px; max-width:85vw; background:#fff; z-index:95; transform:translateX(-100%); transition:transform .22s ease; overflow-y:auto; }
.drawer.open { transform:translateX(0); }
.drawer-head { padding:1rem; font-weight:900; font-size:1.1rem; border-bottom:1px solid var(--line); display:flex; justify-content:space-between; align-items:center; }
.drawer-close { background:none; border:none; font-size:1.4rem; cursor:pointer; color:var(--grey); }
.drawer-section { padding: 0.6rem 0; border-bottom: 1px solid var(--line); }
.drawer-section-title { padding: 0.4rem 1rem; font-size:0.72rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:var(--grey); }
.drawer-row { display:flex; align-items:center; justify-content:space-between; padding:0.65rem 1rem; text-decoration:none; color:var(--ink); font-weight:700; cursor:pointer; border:none; background:none; width:100%; text-align:left; font-size:0.95rem; border-left:4px solid transparent; }
.drawer-row:hover { background:#f2f2ef; }
.drawer-row.active { background:var(--fr-blue); color:#fff; border-left-color:var(--fr-gold); }
.drawer-row.active:hover { background:var(--fr-blue); }
.drawer-row.active::after { content:"\2713"; font-weight:900; color:var(--fr-gold); margin-left:0.5rem; }
.drawer-row[aria-current="page"] { background:#EAF1FB; color:var(--fr-blue); border-left-color:var(--fr-blue); }
.drawer-row[aria-current="page"]:hover { background:#E1EBFA; }
.drawer-sub { padding: 0.35rem 1rem 0.35rem 2rem; display:flex; align-items:center; gap:0.5rem; font-size:0.88rem; border-radius:8px; transition:background .15s ease; }
.drawer-sub input { width:1.05rem; height:1.05rem; accent-color:var(--fr-blue); }
.drawer-sub:has(input:checked) { background:#EAF1FB; }
.drawer-sub:has(input:checked) label { color:var(--fr-blue); font-weight:700; }
.drawer-sub.persona-extra-hidden { display:none; }
.membership-modal { position:fixed; inset:0; z-index:120; display:none; background:rgba(0,0,0,0.5); }
.membership-modal.open { display:flex; align-items:center; justify-content:center; padding:1rem; }
.ms-panel { background:#fff; border-radius:14px; max-width:880px; width:100%; max-height:85vh; display:flex; flex-direction:column; overflow:hidden; }
.ms-head { padding:1rem 1.2rem; border-bottom:1px solid var(--line); display:flex; justify-content:space-between; align-items:center; }
.ms-head h3 { margin:0; font-size:1.1rem; }
.ms-search { padding: 0.8rem 1.2rem 0; }
.ms-search input { width:100%; padding:0.55rem 0.8rem; border-radius:8px; border:1px solid var(--line); font-size:0.92rem; }
.ms-actions { padding: 0.5rem 1.2rem; display:flex; gap:1rem; font-size:0.82rem; }
.ms-actions button { background:none; border:none; color:var(--fr-blue); font-weight:700; cursor:pointer; padding:0; }
.ms-grid { padding: 0.8rem 1.2rem 1.2rem; display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:0.7rem; overflow-y:auto; }
.ms-card { position:relative; border:2px solid var(--line); border-radius:10px; padding:0.6rem; display:flex; flex-direction:column; align-items:center; gap:0.4rem; cursor:pointer; text-align:center; font-size:0.8rem; font-weight:700; }
.ms-card.sel { border-color: var(--tube-green); background:#EAF6EC; box-shadow:0 0 0 1px var(--tube-green); }
.ms-card.sel::after { content:"\2713"; position:absolute; top:0.35rem; right:0.45rem; color:#fff; background:var(--tube-green); width:1.15rem; height:1.15rem; border-radius:50%; font-size:0.68rem; font-weight:900; display:flex; align-items:center; justify-content:center; line-height:1; }
.content { max-width: 1120px; margin: 0 auto; padding: 1.4rem 1rem 3rem; }
.hero-block { position:relative; overflow:hidden; background:var(--fr-blue); color:#fff; border-radius:16px; padding:2.3rem 1.5rem 2.1rem; margin-bottom:1.6rem; }
.hero-glow-red { position:absolute; width:420px; height:420px; right:-120px; top:-180px; border-radius:50%; background:radial-gradient(circle, rgba(239,65,53,0.5) 0%, rgba(239,65,53,0) 70%); pointer-events:none; }
.hero-glow-navy { position:absolute; width:340px; height:340px; left:-130px; bottom:-210px; border-radius:50%; background:radial-gradient(circle, rgba(10,42,87,0.5) 0%, rgba(10,42,87,0) 70%); pointer-events:none; }
.hero-inner { position:relative; z-index:1; max-width:640px; }
.badge-row { display:flex; flex-wrap:wrap; gap:0.5rem; margin-bottom:1rem; }
.pill { display:inline-flex; align-items:center; gap:0.35rem; background:rgba(255,255,255,0.14); border:1px solid rgba(255,255,255,0.22); color:#fff; font-size:0.74rem; font-weight:700; letter-spacing:0.01em; padding:0.36rem 0.65rem; border-radius:999px; }
.pill.gold { background:rgba(255,199,44,0.18); border-color:rgba(255,199,44,0.42); color:var(--fr-gold); }
.hero-block h1 { font-weight:700; font-size:clamp(1.7rem,5vw,2.5rem); line-height:1.08; margin:0 0 0.6rem; letter-spacing:-0.01em; }
.hero-block h1 span { color:var(--fr-gold); }
.hero-block p { margin:0 0 1.3rem; color:rgba(255,255,255,0.9); font-weight:400; max-width:56ch; line-height:1.5; }
.hero-cta-row { display:flex; flex-wrap:wrap; align-items:center; gap:1rem; }
.hero-cta { display:inline-flex; align-items:center; gap:0.4rem; background:var(--fr-gold); color:var(--ink); font-weight:700; font-size:0.92rem; padding:0.75rem 1.3rem; border-radius:10px; text-decoration:none; box-shadow:0 8px 18px rgba(0,0,0,0.22); }
.hero-cta-ghost { color:rgba(255,255,255,0.88); font-weight:600; font-size:0.88rem; border-bottom:1px solid rgba(255,255,255,0.42); padding-bottom:2px; text-decoration:none; background:none; border-top:none; border-left:none; border-right:none; cursor:pointer; font-family:inherit; }
.brand-carousel { overflow:hidden; position:relative; padding: 0.3rem 0.1rem 1rem; margin-bottom: 0.6rem;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.brand-carousel-track { display:flex; gap:0.8rem; width:max-content; animation: brand-scroll 38s linear infinite; }
.brand-carousel:hover .brand-carousel-track, .brand-carousel:focus-within .brand-carousel-track { animation-play-state: paused; }
.brand-carousel-set { display:flex; gap:0.8rem; flex:0 0 auto; }
@keyframes brand-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.brand-card { flex: 0 0 auto; border:1px solid var(--line); border-radius:12px; background:#fff; padding:0.7rem 1rem; display:flex; align-items:center; justify-content:center; min-width:110px; text-decoration:none; box-shadow:0 1px 2px rgba(10,42,87,0.04); transition: transform .15s ease, box-shadow .15s ease; }
.brand-card:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,15,88,0.14); }
@media (prefers-reduced-motion: reduce) {
  .brand-carousel { overflow-x:auto; -webkit-mask-image:none; mask-image:none; }
  .brand-carousel-track { animation:none; width:auto; }
  .brand-carousel-set[aria-hidden="true"] { display:none; }
}
.cat-list { display:grid; grid-template-columns: 1fr; gap: 0.6rem; }
@media (min-width:860px) { .cat-list { grid-template-columns: repeat(2,1fr); } }
@media (min-width:1320px) { .cat-list { grid-template-columns: repeat(3,1fr); } }
.cat-row { display:flex; align-items:center; gap:0.9rem; padding:0.9rem 1rem; background:#fff; border:1px solid var(--line); border-radius:12px; text-decoration:none; color:var(--ink); box-shadow:0 1px 2px rgba(10,42,87,0.04); transition: transform .12s ease, box-shadow .12s ease; }
.cat-row:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0,15,88,0.12); }
.cat-icon { width:44px; height:44px; min-width:44px; border-radius:10px; display:flex; align-items:center; justify-content:center; color:#fff; }
.cat-icon svg { width:22px; height:22px; }
.cat-icon-light { width:88px; height:88px; min-width:88px; border-radius:14px; background:var(--paper); border:1px solid var(--line); }
.cat-icon-anim { width:56px; height:56px; object-fit:contain; display:block; }
.cat-row-label { font-weight:800; flex-grow:1; }
.cat-row-count { font-weight:700; color:var(--grey); font-size:0.88rem; }
.cat-row-chevron { color:var(--grey); font-size:1.3rem; }
.section-title { font-weight:900; font-size:1.15rem; margin: 1.6rem 0 0.8rem; scroll-margin-top: 150px; }
.merchant-grid { display:grid; grid-template-columns:1fr; gap:1rem; }
@media (min-width:860px) { .merchant-grid { grid-template-columns:repeat(2,1fr); } }
@media (min-width:1320px) { .merchant-grid { grid-template-columns:repeat(3,1fr); } }
.mini-card { display:flex; align-items:center; gap:0.8rem; padding:0.9rem 1rem; background:#fff; border:1px solid var(--line); border-radius:12px; text-decoration:none; color:var(--ink); box-shadow:0 1px 2px rgba(10,42,87,0.04); }
.mini-card:hover { box-shadow:0 8px 20px rgba(0,15,88,0.1); transform:translateY(-2px); }
.mini-card-name { font-weight:800; }
.mini-card-sub { font-size:0.78rem; color:var(--grey); }
.net-logo, .net-logo-fallback { border-radius:10px; border:1px solid var(--line); box-shadow:0 2px 8px rgba(0,15,88,0.1); object-fit:contain; background:#fff; }
/* when a logo already sits inside its own card (.brand-card, .mini-card), it
   shouldn't ALSO carry its own border/background/shadow - that reads as a box
   nested inside a box. The outer card supplies the chrome; the logo here is
   just the image, borderless and transparent. */
.brand-card .net-logo, .brand-card .net-logo-fallback,
.mini-card .net-logo, .mini-card .net-logo-fallback {
  border:none; box-shadow:none; background:transparent; border-radius:0;
}
.net-logo-fallback { display:inline-flex; align-items:center; justify-content:center; color:#fff; font-weight:900; }
/* Merchant/network detail header: logo is a fixed-size box that never shrinks
   or wraps away; the name+count column takes the remaining space and wraps
   WITHIN itself. This guarantees the exact same side-by-side layout on every
   page regardless of how long the name is - previously flex-wrap on the row
   let long names (e.g. "Sveland Djurförsäkringar") drop below the logo while
   short ones (e.g. "ThermoBar") stayed beside it, so the page looked
   differently structured depending on name length. */
.merchant-head { display:flex; align-items:center; flex-wrap:nowrap; gap:1.1rem; margin-bottom:1rem; padding:1.1rem; background:var(--card); border:1px solid var(--line); border-radius:14px; box-shadow:0 1px 2px rgba(10,42,87,0.04); }
/* The header logo identifies the whole page (the one company/network you're
   currently looking at), so it must read as the single biggest logo on the
   page - bigger than every route-card logo in the list below it at every
   breakpoint. A CSS override (below) sets its size explicitly at all three
   tiers rather than trusting the inline size the template passes in, so
   this stays true regardless of what size generate_site.py happens to pass
   logo_html() for a given page (72 for merchant pages, 60 for network
   pages) - those become irrelevant once these rules apply. */
.merchant-head .net-logo, .merchant-head .net-logo-fallback { flex-shrink:0; width:180px !important; height:82px !important; }
.merchant-head .net-logo-fallback { font-size:40px !important; }
.merchant-head-info { min-width:0; }
.merchant-title { font-weight:900; font-size:clamp(1.05rem, 4.6vw, 1.6rem); line-height:1.25; margin:0; overflow-wrap:break-word; hyphens:auto; }
.route-count { font-size:0.82rem; color:var(--grey); font-weight:700; margin-top:0.3rem; }
.persona-row-hint { font-size:0.85rem; color:var(--grey); margin: 0 0 1.1rem; }
/* Each "route" (a way to unlock the offer) is its own card, matching the
   rounded/bordered card language used everywhere else on the site
   (.cat-row, .brand-card, .mini-card) instead of a plain divided list -
   so the page reads as one consistent design system. */
.route { position:relative; display:flex; align-items:flex-start; gap:0.9rem; padding:1rem 1.1rem; background:var(--card); border:1px solid var(--line); border-radius:14px; box-shadow:0 1px 2px rgba(10,42,87,0.04); margin-bottom:0.9rem; }
[data-route-list] .route:last-child { margin-bottom:0; }
/* Each route card leads with a big, easy-to-spot logo on the far left (the
   merchant's logo on a membership/network page, the network's logo on a
   merchant page) - reuses the same sourced /logos/*.webp files as everywhere
   else on the site, just rendered larger here since a whole list of these
   is the primary way people scan for "is my card/company on this list". The
   logo never shrinks or wraps; the text column takes the remaining width. */
.route .net-logo, .route .net-logo-fallback { flex-shrink:0; }
.route-body { display:flex; flex-direction:column; align-items:flex-start; gap:0.55rem; min-width:0; flex:1; }
/* The header row holds ONLY the network/merchant name - nothing else
   competes with it for width, which is most of why a long name has a
   decent shot at fitting on one line. padding-right reserves space so it
   never runs underneath the corner badge (see .corner-badge below), which
   sits in the card's top-right corner independent of this row's layout. */
.route-net { font-weight:700; font-size:0.92rem; line-height:1.4; padding-right:2.3rem; }
/* Ownership status ("Du har detta"/"Du har inte detta") as a small circular
   badge pinned to the route card's top-right corner, replacing the earlier
   full-width text pill - a pill took a whole extra row for what's really
   just a status flag, competing with the discount/requirements for
   attention instead of staying out of the way. position:absolute takes it
   out of the card's normal flow/grid entirely, so it never affects where
   the logo/title/body land (and doesn't need separate handling in the
   mobile grid layout below). Rendered as a same-position pair (only one
   visible at a time via the .owned class, same JS-driven toggle as before)
   so there's no layout shift either way. */
.corner-badge { position:absolute; top:0.75rem; right:0.75rem; width:1.9rem; height:1.9rem; border-radius:50%; display:none; align-items:center; justify-content:center; font-weight:900; font-size:0.85rem; line-height:1; cursor:default; box-shadow:0 1px 3px rgba(10,42,87,0.14); }
.corner-badge-owned { background:#EAF6EC; color:var(--tube-green); border:1.5px solid #BEE6C5; }
.corner-badge-notowned { background:#FDEAEA; color:var(--fr-red); border:1.5px solid #F5C2BE; }
.route.owned .corner-badge-owned { display:flex; }
html.ms-ready .route:not(.owned) .corner-badge-notowned { display:flex; }
.corner-badge:focus-visible { outline:none; box-shadow:0 0 0 3px rgba(0,85,164,0.35); }
/* Full wording ("Du har detta"/"Du har inte detta") is still there for
   anyone who wants it - just not shown by default. Hovering with a mouse,
   or focusing the badge (tab key, or tap-to-focus on touch) reveals it as a
   small tooltip; screen readers get the same text unconditionally via
   role="img" + aria-label on the badge itself (set in generate_site.py),
   independent of whether the tooltip is visually shown. */
.corner-tooltip { position:absolute; top:calc(100% + 0.45rem); right:0; background:var(--fr-navy); color:#fff; font-size:0.72rem; font-weight:700; padding:0.35rem 0.65rem; border-radius:6px; white-space:nowrap; opacity:0; pointer-events:none; transform:translateY(-4px); transition:opacity 0.15s ease, transform 0.15s ease; box-shadow:0 4px 10px rgba(0,15,88,0.2); z-index:5; }
.corner-badge:hover .corner-tooltip, .corner-badge:focus .corner-tooltip { opacity:1; transform:translateY(0); }
/* The discount is the actual reason anyone opens this card, so it's the
   single most visually dominant piece of text in the whole route body -
   bigger and bolder than the network/merchant name above it. Everything
   else in the card (tag, access requirement, any split-off booking detail)
   is deliberately smaller than this and grouped together below it as one
   small-text "fine print" block instead of competing pills. */
.route-val { font-weight:800; font-size:1rem; line-height:1.35; color:var(--tube-green); background:#EAF6EC; border-radius:8px; padding:0.5rem 0.7rem; display:inline-block; width:fit-content; }
/* Applied by route_val_html() (generate_site.py) when the discount text is
   long (>90 chars) and had no safe split point - e.g. the 354-character
   LEGOLAND multi-benefit list. Still the one highlighted/colored element on
   the card, just not shouting an entire paragraph in the same huge bold
   type meant for a punchy one-line discount. */
.route-val-long { font-weight:700; font-size:0.84rem; line-height:1.4; }
/* A trailing logistics/contact clause split off the discount text by
   route_val_html() - e.g. "(valid 4 mars 2026 - 31 aug. 2026; show
   Westfield Club member number/EAN code at checkout)" or "Boka via
   info@klotenresort.se eller 0580-88300, kod B24." Real information, but a
   continuation/footnote of the discount above it, not part of the headline
   - small and muted like the rest of the fine print below. */
.route-val-detail { font-size:0.78rem; line-height:1.4; color:var(--grey); margin-top:-0.15rem; }
/* The `tag` field (e.g. "Gäller endast online", "+ Fri frakt") as a small
   plain line, not a colored badge - of 298 distinct tag values in the
   data, well under half read as an actual restriction; the rest are bonus
   extras, plain repeats of the discount percentage, or marketing lines.
   Giving all of it equal loud colored-chip treatment overstated its
   importance; grouped here with the other fine print, it's shown exactly
   as prominently as it usually deserves. */
.route-tag-line { font-size:0.78rem; font-weight:600; line-height:1.4; color:var(--grey); }
/* Access-requirement line (the route's `login` field) - e.g. "Löses in i
   Lidl-appen, kräver aktivt Lidl Plus-medlemskap". Real, useful info, but
   not what a user scans for first, so it's the same small/muted treatment
   as the rest of the fine-print block above and below it. */
.route-note { font-size:0.8rem; font-weight:600; line-height:1.4; color:#6E6E6E; margin-top:-0.1rem; }
/* Trailing parenthetical aside split out of the login text by
   route_note_html() in generate_site.py - e.g. "(gratis att gå med, kräver
   inte att man äger en OBOS-bostad)". Extra context, not something most
   users need to read every time, so it's smaller and lighter still than
   .route-note right above it. */
.route-subnote { font-size:0.72rem; line-height:1.35; color:var(--grey); margin-top:-0.15rem; }
.ticket-btn { font-size:0.85rem; font-weight:800; color:#fff; background:var(--fr-blue); text-decoration:none; padding:0.6rem 1rem; border-radius:8px; display:inline-block; }
.ticket-btn:hover { background:var(--fr-red); }
/* On narrow phones there's no room for a big logo AND a long name side by
   side, so the header switches to a stacked layout: a full-width logo
   banner on top, the name/count block below it - rather than shrinking the
   logo down small (which is what happened before and made it read as LESS
   important than the logos in the route cards underneath it, backwards
   from the actual hierarchy). object-fit:contain (set globally on
   .net-logo) keeps non-square logos centered and undistorted inside the
   full-width box instead of stretching them.

   These two @media blocks are deliberately placed here, AFTER the base
   .route/.route-body/.route-val/etc. rules above rather than near the top
   of the stylesheet - a media-query rule and a plain rule that both target
   the exact same selector (e.g. plain ".route") have EQUAL CSS specificity,
   so when both match (mobile viewport), the cascade falls back to source
   order and whichever is written LATER in the file wins. Having a
   `@media (max-width:420px) { .route {...} }` block earlier in the file
   than the base `.route {...}` rule meant the base rule silently overrode
   it on real phones - a real bug from an earlier round, worth flagging so
   nobody moves this block back above the base rules by mistake. */
@media (max-width:420px) {
  .merchant-head { flex-direction:column; align-items:stretch; gap:0.7rem; padding:0.9rem; }
  .merchant-head .net-logo, .merchant-head .net-logo-fallback { width:100% !important; height:120px !important; }
  .merchant-head .net-logo-fallback { font-size:56px !important; }
  /* Route cards on mobile: the logo becomes a floating badge, centered on
     the card's top edge with roughly half poking above the card and half
     sitting inside it (a "membership card" look, per Ahmed's request),
     instead of sitting inline to the left of the name. Once the logo is
     out of the horizontal flow (position:absolute, centered), .route-body
     no longer shares its row with anything - it can just be a normal
     full-width block, so every child (discount, fine print, CTA) is
     naturally full-width with no grid/display:contents trick needed. This
     also means nothing competes with the name for horizontal room, so long
     names have an even better shot at fitting on one line than the
     previous side-by-side layout did. padding-top on .route reserves room
     for the inside half of the logo plus a small gap before the name
     starts. The corner ownership badge (.corner-badge) is unaffected -
     still its own absolutely-positioned top-right icon, clear of the
     centered logo at every card width this site supports. Laptop/tablet
     are untouched - this whole block only applies under 420px. */
  /* margin-bottom is bumped well past the base 0.9rem here specifically to
     clear the floating logo above: the logo pokes 38px above ITS OWN
     card's top edge, so the gap before it needs to be bigger than that or
     it visually overlaps the card above (its button, in particular) -
     verified this was actually happening at 0.9rem before widening it. */
  .route { display:block; padding:3.5rem 0.9rem 0.85rem; margin-bottom:3.4rem; }
  /* The FIRST card in a list has no previous card's margin-bottom to give
     it clearance - without this, its floating logo pokes up 38px into the
     "Erbjudanden nedan..." hint paragraph right above the list (verified
     this was actually happening before adding it). */
  .route:first-child { margin-top:2.2rem; }
  .route .net-logo, .route .net-logo-fallback { position:absolute; top:-38px; left:50%; transform:translateX(-50%); width:150px !important; height:76px !important; z-index:2; }
  .route-body { display:flex; flex-direction:column; align-items:stretch; gap:0.55rem; }
  .route-net { text-align:center; padding-right:0; font-size:0.88rem; }
  /* route-val normally caps its own width to fit-content (a compact pill on
     laptop); here it stretches to the card's full width like everything
     else in the body, via align-items:stretch on .route-body above. */
  .route-val, .route-val-long { width:auto; display:block; }
  .ticket-btn { text-align:center; }
}
/* Above phone width the base (inline, template-set) route logo size of 64px
   already applies with no override needed. On real laptop/desktop widths
   there's plenty of spare card width (.content caps at 1120px), so the logo
   goes noticeably bigger again - it's the main visual anchor for scanning a
   long list of offers, worth the extra size once there's room for it. Still
   kept smaller than the header logo's 140px at this same tier (below). */
@media (min-width:681px) {
  .route .net-logo, .route .net-logo-fallback { width:246px !important; height:112px !important; }
  .merchant-head .net-logo, .merchant-head .net-logo-fallback { width:308px !important; height:140px !important; }
  .merchant-head .net-logo-fallback { font-size:64px !important; }
}
.persona-empty { display:none; background:#F5F8FF; border:1px dashed var(--fr-blue); border-radius:12px; padding:1.3rem 1.1rem; text-align:center; margin-top:0.6rem; }
.persona-empty p { margin:0 0 0.9rem; color:var(--ink); font-size:0.9rem; font-weight:600; }
.persona-empty-switch { background:var(--fr-blue); color:#fff; border:none; border-radius:8px; padding:0.6rem 1.1rem; font-weight:700; cursor:pointer; font-size:0.88rem; font-family:inherit; }
.persona-empty-switch:hover { background:#004488; }
.empty { text-align:center; padding:3rem 1rem; color:var(--grey); font-weight:600; }
.site-footer { background:var(--fr-navy); color:rgba(255,255,255,0.72); margin-top:2.4rem; }
.site-footer-inner { max-width:1120px; margin:0 auto; padding: 2.2rem 1rem 1.6rem; display:flex; flex-wrap:wrap; gap:2.4rem; justify-content:space-between; }
.footer-brand-row { display:flex; align-items:center; gap:0.5rem; margin-bottom:0.5rem; }
.footer-logo-mark { display:block; height:34px; width:auto; }
.footer-logo-text { font-weight:700; font-size:1.05rem; color:#fff; }
.footer-logo-text .lg2 { color:var(--fr-gold); }
.footer-tagline { margin:0; font-size:0.85rem; max-width:260px; line-height:1.5; }
.footer-links { display:flex; flex-wrap:wrap; gap:2.8rem; }
.footer-col-title { font-size:0.72rem; font-weight:800; text-transform:uppercase; letter-spacing:0.06em; color:rgba(255,255,255,0.45); margin-bottom:0.7rem; }
.footer-col a { display:block; color:#fff; text-decoration:none; font-size:0.9rem; font-weight:600; margin-bottom:0.55rem; }
.footer-col a:hover { color:var(--fr-gold); }
.footer-bottom { max-width:1120px; margin:0 auto; padding: 1.1rem 1rem 1.6rem; border-top:1px solid rgba(255,255,255,0.14); display:flex; flex-wrap:wrap; gap:0.4rem 1.2rem; justify-content:space-between; font-size:0.78rem; color:rgba(255,255,255,0.5); }
.footer-bottom a { color:rgba(255,255,255,0.7); text-decoration:underline; }
.breadcrumb { font-size:0.82rem; color:var(--grey); margin-bottom:0.8rem; }
.breadcrumb a { text-decoration:none; color:var(--fr-blue); }
[data-personas].persona-hidden { display:none !important; }
/* Cookie-consent banner (GA4). Hidden by default (transform pushes it off
   the bottom edge) - shown only via JS, and only for a visitor who hasn't
   already made a choice (see BASE_JS). Fixed positioning + high z-index so
   it sits above everything else, matching the drawer/modal layer pattern
   already used elsewhere on the site. */
.cookie-consent { position:fixed; left:0; right:0; bottom:0; z-index:150; background:var(--fr-navy); color:#fff; box-shadow:0 -4px 18px rgba(0,15,88,0.25); transform:translateY(110%); transition:transform 0.25s ease; }
.cookie-consent.show { transform:translateY(0); }
.cookie-consent-inner { max-width:1120px; margin:0 auto; padding:1rem 1.1rem; display:flex; flex-wrap:wrap; align-items:center; gap:0.9rem 1.4rem; justify-content:space-between; }
.cookie-consent-inner p { margin:0; font-size:0.85rem; line-height:1.5; color:rgba(255,255,255,0.92); max-width:640px; flex:1 1 260px; }
.cookie-consent-actions { display:flex; gap:0.6rem; flex-shrink:0; }
.cookie-btn { font-size:0.85rem; font-weight:700; padding:0.55rem 1.05rem; border-radius:8px; cursor:pointer; border:none; font-family:inherit; }
.cookie-btn-solid { background:var(--fr-gold); color:var(--ink); }
.cookie-btn-solid:hover { filter:brightness(0.95); }
.cookie-btn-ghost { background:rgba(255,255,255,0.12); color:#fff; border:1px solid rgba(255,255,255,0.3); }
.cookie-btn-ghost:hover { background:rgba(255,255,255,0.2); }
/* Clerk auth slot in the drawer's "Mitt konto" section - starts as plain
   loading text (see cookie-consent-html's sibling markup above) and gets
   replaced by JS once Clerk has loaded: either a mounted UserButton (signed
   in) or "Logga in"/"Skapa konto" buttons (signed out), styled to match the
   existing .drawer-row buttons so it reads as part of the same menu rather
   than a bolted-on widget. */
.clerk-auth-loading { display:block; padding:0.5rem 1rem; font-size:0.85rem; color:var(--grey); }
.clerk-auth-slot .drawer-row { border-left:4px solid transparent; }
/* Custom identity row (photo, then name+email stacked) - see renderAuthSlot()
   in BASE_JS. A plain button styled to sit flush in the drawer like every
   other .drawer-row, not a bolted-on card. */
#clerkUserButtonWrap.clerk-identity-row {
  display:flex; align-items:center; gap:0.7rem; width:100%; padding:0.6rem 1rem;
  background:none; border:none; cursor:pointer; text-align:left; font-family:inherit;
}
#clerkUserButtonWrap.clerk-identity-row:hover { background:#F5F6F8; }
#clerkUserButtonWrap .clerk-avatar { width:36px; height:36px; border-radius:50%; object-fit:cover; flex:none; background:#E4E6EA; }
#clerkUserButtonWrap .clerk-identity-text { display:flex; flex-direction:column; min-width:0; }
#clerkUserButtonWrap .clerk-identity-name { font-size:0.95rem; font-weight:600; color:var(--dark); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
#clerkUserButtonWrap .clerk-identity-email { font-size:0.8rem; color:var(--grey); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (max-width:480px) {
  /* flex-basis is direction-relative: the base rule's "flex:1 1 260px" on
     the paragraph sets a *width* basis in row mode, but once this switches
     to column mode that same 260px basis applies to HEIGHT instead -
     stretching the paragraph to a 260px-tall box for no reason. Reset it
     to flex:none here so column mode sizes the paragraph by its actual
     content height, not a stale width value. */
  .cookie-consent-inner { flex-direction:column; align-items:stretch; justify-content:flex-start; gap:0.8rem; }
  .cookie-consent-inner p { flex:none; max-width:none; }
  .cookie-consent-actions { justify-content:flex-end; }
}
